在简单工厂中,工厂类决定具体去实例化哪一个类,而在工厂方法中,由客户端决定去实例化哪一个类。
简单工厂模式的缺点也显而易见,它对“开闭原则”的支持不足,当添加新的产品时,势必会修改客户端和工厂类两个地方的代码。
工厂方法模式是对简单工厂的进一步抽象和优化,在工厂方法中,工厂类转为了抽象工厂类,只负责规定具体工厂子类需要实现的接口,具体产品创建的工作交给了子类去做。
优缺点
- 优点
当添加新的产品时,只需要添加一个抽象工厂类的子类,工厂端只有扩展的工作。
- 缺点
决定创建哪个产品的工作转移到了客户端,客户端需要确定要去创建哪个对象,当添加新产品时,客户端会修改代码。可以说,简单工厂是客户端和工厂都不支持开闭原则,而工厂方法工厂端支持开闭原则,而客户端依然不支持开闭原则。
Java中的工厂方法
Collection类是工厂方法模式中的抽象工厂,其中定义的
/**
* Returns an iterator over the elements in this collection. There are no
* guarantees concerning the order in which the elements are returned
* (unless this collection is an instance of some class that provides a
* guarantee).
*
* @return an <tt>Iterator</tt> over the elements in this collection
*/
Iterator<E> iterator();
就是工厂方法,每一个实现Collection的子类都要实现该方法。当客户端调用每个Collection子类时,都可以通过iterator()获得一个具体的Iterator类。
实例
- 牛奶抽象接口
package com.faith.net;
/**
* 牛奶抽象接口
*/
public interface Milk {
/**
* 获取一个标准产品
* @return
*/
public String getName();
}
- 特仑苏牛奶
package com.faith.net;
/**
* 特仑苏
*/
public class Telunsu implements Milk {
@Override
public String getName() {
return "特仑苏";
}
}
- 伊利牛奶
package com.faith.net;
/**
* 伊利
*/
public class Yili implements Milk {
@Override
public String getName() {
return "伊利";
}
}
- 抽象工厂类
package com.faith.net.func;
import com.faith.net.Milk;
/**
* 抽象工厂类
*/
public interface MikeFactory {
//工厂必然具有生产产品技能,统一的产品出口
Milk getMilk();
}
特仑苏工厂
package com.faith.net.func;
import com.faith.net.Milk;
import com.faith.net.Telunsu;
/**
* 特仑苏工厂
*/
public class TelunsuMikeFactory implements MikeFactory {
@Override
public Milk getMilk() {
return new Telunsu();
}
}
伊利工厂
package com.faith.net.func;
import com.faith.net.Milk;
import com.faith.net.Yili;
/**
* 伊利工厂
*/
public class YiliMikeFactory implements MikeFactory {
@Override
public Milk getMilk() {
return new Yili();
}
}
- 客户端
package com.faith.net.func;
/**
* 客户端
*/
public class FactoryTest {
public static void main(String[] args) {
MikeFactory mikeFactory = new SanluMikeFactory();
System.out.println(mikeFactory.getMilk());
}
}