工厂方法模式
一、介绍
定义: 工厂方法模式,又称工厂模式、多态工厂模式和虚拟构造器模式。定义一个工厂父类负责创建工厂子类的公共接口,而工厂子类则负责生成具体的产品对象。
工厂方法模式解决了简单工厂模式的缺点:
工厂一旦需要扩展新的产品就需要修改工厂类的逻辑,违背“开闭原则”。
工厂方法模式把具体产品的创建放到工厂类的子类(具体工厂)中,工厂类不再负责所有产品的创建,而是给出具体工厂必须实现的接口,这样在添加新产品的时候就可以不修改工厂类逻辑而是直接重写父类接口中的方法,符合“开闭原则”。
二、特点
优点:
- 更加符合“开闭原则”: 新扩展一种产品时,只需要增加相应的具体产品类和相应的具体工厂类即可。(而简单工厂需要修改工厂类的逻辑代码);
- 符合单一职责原则 :每个具体工厂类只负责创建对应的具体产品(而简单工厂类中使用复杂的switch逻辑判断创建各种产品);
- 不使用静态工厂方法,可以形成接口继承的结构。(而简单工厂使用静态工厂方法)
缺点:
- 扩展新产品时,除了增加新产品类外,还要增加与之对应的具体工厂类,类的个数将成对增加,一定程度上增加了系统的复杂度;同时有更多的类需要编译和运行,会给系统带来一些额外的开销;
- 考虑到系统的可扩展性,引入抽象层,在客户端代码中均使用抽象层进行定义,增加了系统的抽象性和理解难度,且在实现时可能需要用到DOM、反射等技术,增加了系统的实现难度;
- 一个具体工厂只能创建一种具体产品;
- 虽然保证了工厂方法内的对修改关闭,但对于使用工厂方法的类,如果要更换另外一种产品,仍然需要修改实例化的具体工厂类;
三、使用场景
- 在工厂方法模式中,客户端不需要知道具体产品类的类名,只需要知道所对应的工厂即可;
- 当一个类希望通过其子类来指定创建对象时
- 在工厂方法模式中,对于抽象工厂类只需要提供一个创建产品的接口,而由其子类来确定具体要创建的对象,使得系统更容易扩展。
- 将创建对象的任务委托给多个工厂子类中的某一个,客户端在使用时可以无须关心是哪一个工厂子类创建产品子类,需要时再动态指定,可将具体工厂类的类名存储在配置文件或数据库中。
四、类图
角色:
抽象产品(Product): 具体产品的父类, 描述具体产品的公共接口
具体产品(Concrete Product): 抽象产品的子类 ,描述生产的具体产品
抽象工厂(Factory): 具体工厂的父类,描述具体工厂的公共接口
具体工厂(Concrete Factory): 抽象工厂的子类,描述具体工厂
五、实战代码
有一个水果加工厂(仅加工苹果);随着客户需求的变化,客户需要加工香蕉。
决定建造一个水果分厂来专门加工香蕉。
步骤1. 创建抽象工厂类
【FruitFactory .java】
package com.factory;
public interface FruitFactory {
//加工水果的抽象方法
public abstract Fruit Creat();
}
步骤2. 创建抽象产品类
【ProductA .java】
package com.factory;
public interface Fruit {
//显示加工信息
public abstract void show();
}
步骤3. 创建具体产品类
【Apple .java】
package com.factory;
public class Apple implements Fruit {
//显示加工完成
public void show() {
System.out.println("Apple加工完成!");
}
}
【Banana .java】
package com.factory;
public class Banana implements Fruit {
//显示加工完成
public void show() {
System.out.println("Banana加工完成!");
}
}
步骤4. 创建具体工厂类
【FactoryApple .java】
package com.factory;
public class FactoryApple implements FruitFactory {
//Apple工厂创建Apple
public Fruit Creat() {
return new Apple();
}
}
【FactoryBanana .java】
package com.factory;
public class FactoryBanana implements FruitFactory {
//Banana工厂创建Banana
public Fruit Creat() {
return new Banana();
}
}
步骤5. 客户端创建不同具体产品类
【Client .java】
package com.factory;
public class Client {
public static void main(String[] args) {
//创建两个水果加工厂
FactoryApple aFactory = new FactoryApple();
FactoryBanana bFactory = new FactoryBanana();
//显示加工信息
aFactory.Creat().show();
bFactory.Creat().show();
}
}
【运行截图】
喜欢的话记得点赞收藏哟😊
Java设计模式—博文专栏持续更新!