工厂方法模式
引入
针对简单工厂的缺点
- 所有的逻辑都在工厂类中。一旦工厂内不能工作,整个系统均受影响。
- 系统拓展困难。添加新的产品,最后必须修改工厂逻辑
进行改进, 不再设计一个工厂类来负责所有的实例创建, 而是将具体实例A交给具体工厂A创建, 具体实例B交给具体工厂B创建. 这种改进的结果是可以在不修改具体工厂类的情况下引入新的产品。如果出现新的产品类型。只需要为这种新的类型,新建一个具体工厂类
定义
工厂父类负责定义创建产品对象的公共接口。而工厂子类则负责生成具体的产品对象。将产品的实例化操作延迟到工厂子类中完成
代码分析
//测试
public class Client {
public static void main(String[] args) {
IFactory facA = new FactoryA();
IProduct proAA = facA.createProduct("aa");
proAA.use();
IProduct proAB = facA.createProduct("AB");
proAB.use();
IFactory facB = new FactoryB();
facB.createProduct("ba").use();
facB.createProduct("BB").use();
}
}
//工厂接口
public interface IFactory {
public IProduct createProduct(String type);
}
//具体工厂A
public class FactoryA implements IFactory {
@Override
public IProduct createProduct(String type) {
if("aa".equalsIgnoreCase(type)) {
return new ProductAA();
}else if("AB".equalsIgnoreCase(type)) {
return new ProductAB();
}else {
return null;
}
}
}
//具体工厂A生产的产品A
public class ProductAA implements IProduct {
@Override
public void use() {
System.out.println("productAA is used!");
}
}
//具体工厂A生产的产品B
public class ProductAB implements IProduct {
@Override
public void use() {
System.out.println("productAB is used!");
}
}
//////////////////////////////////////////////////////////
// 新增一个产品, 需要新增针对它的具体工厂
// 因业务需求,新增工厂B,代码拓展
//新增具体工厂B
public class FactoryB implements IFactory {
@Override
public IProduct createProduct(String type) {
if("ba".equalsIgnoreCase(type)) {
return new ProductBA();
}else if("BB".equalsIgnoreCase(type)) {
return new ProductBB();
}
return null;
}
}
//工厂B生产产品BA
public class ProductBA implements IProduct {
@Override
public void use() {
System.out.println("productBA is used!");
}
}
//工厂B生产的产品BB
public class ProductBB implements IProduct {
@Override
public void use() {
System.out.println("productBB is used!");
}
}
模式分析
- 工厂方法模式是简单工厂模式的进一步抽象。并且克服了他的缺点, 将具体的创建工作交给工厂子类去做。工厂抽象类仅仅负责给出创建产品必须的接口。使得系统在不修改工厂角色的情况下引入新产品。符合了开闭原则
- 使用多个重载的工厂方法: 在抽象工厂角色中可以定义多个工厂方法。这些方法可以包含不同的业务逻辑以满足不同产品对象的需求。
- 产品对象的重复使用: 工厂将已经创建过的对象存储到一个集合中。然后根据客户端对产品的请求对集合进行查询。如果满足查询请求则返回,如果不满足。创建新的对象。然后将该对象返回到客户端。
- 当只有一个具体工厂时那么便发生退化变为简单工厂模式
- 抽象工厂模式:工厂方法模式与抽象工厂模式最大的区别在于,在工厂方法模式中,工厂创造的是一个产品,而在抽象工厂模式中,工厂创造的是一个产品族(比如组成一台电脑的屏幕, 键盘, 鼠标等等)
优点:
首先具有简单工厂的优点
- 对象的创建和消费实现了分离
- 知道参数, 即可创建对象实例, 简单
此外修复了简单工厂缺点
- 所有的逻辑都不在同一个工厂类中。一旦一个工厂类不能工作,整个系统不受影响。
- 系统拓展容易。添加新的产品,无须修改原有工厂逻辑, 只需新增产品类和对应工厂类
缺点:
- 添加新产品时, 需要一个产品类, 和对应的工厂类, 类文件个数将成对增加, 复杂
使用场景
选择关键点:工厂类和产品类是否是同生同灭的关系
- 客户端只知道具体工厂类和产品参数
- 将创建对象的任务委托给多个工厂子类中的一个, client无需关心到底是哪个工厂子类, 需要时再动态指定, 可以将工厂子类的类名存储在配置文件中or数据库中