1. 简单工厂模式
1.1 定义
简单工厂模式(Simple Factory Pattern):又称为静态工厂方法(Static Factory Method)模式,它属于类创建型模式。在简单工厂模式中,可以根据参数的不同返回不同类的实例。简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。
1.2 结构
- Product: 抽象产品角色
抽象产品角色是所有产品的父类,提供产品的公共行为
- ConcreteProduct:具体产品角色
具体产品角色是创建目标,所有创建的对象的实例
- Factory: 工厂角色
工厂角色负责创建所有对象
1.3 场景案例
通过简单工厂模式实现一个计算器的程序,需要完成两个数字的加减乘除操作
计算器设计类图:
实现代码:
design_mode/src/main/java/com/nongminggong/factory/simple at liuyu · constantRAIN/design_mode
客户端调用代码
代码语言:java复制public class OperationClient {
public static void main(String[] args) {
OperationNumber operationNumber = new OperationNumber(10, 5);
// 加法
Operation operationAdd = OperationFactory.createOperation(" ");
double addResult = operationAdd.operate(operationNumber);
System.out.println("加法结果" addResult);
// 减法
Operation operationSub = OperationFactory.createOperation("-");
double subResult = operationSub.operate(operationNumber);
System.out.println("减法结果" subResult);
// 乘法
Operation operationMul = OperationFactory.createOperation("*");
double mulResult = operationMul.operate(operationNumber);
System.out.println("乘法结果" mulResult);
// 除法
Operation operationDiv = OperationFactory.createOperation("/");
double divResult = operationDiv.operate(operationNumber);
System.out.println("除法结果" divResult);
}
}
执行结果:
1.4 优缺点
优点:
- 工厂类包含了必要的判断逻辑,可以根据传入的参数来创建对象
- 将业务逻辑对调用方进行隐藏,调用方不用关系具体的实现
- 相对提高了代码的扩展性、复用性以及可维护性(例如新增一个类型,只需要创建新的类,然后工厂实现对象的创建即可,不会对已存在的功能造成影响)
- 具体运算类遵循了开闭原则
缺点:
- 因为工厂类只有一个,如果出现问题,整个系统将收到影响
- 增加了类的个数,在一定程度上提升了系统的复杂度
- 系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,在产品类型较多时,有可能造成工厂逻辑过于复杂,不利于系统的扩展和维护
- 工厂类违背了开闭原则
1.5 使用场景
- 工厂类复杂创建的对象比较少
- 客户端不关心对象创建,不关心功能实现细节,只需要知道对象创建的类型
2. 工厂方法模式
2.1 定义
工厂方法模式(Factory Methon Pattern) 又称 工厂模式,也叫虚拟构造器(Virtual Constructor)模式或者多态工厂(Polymorphic Factory)模式, 它属于创建型模式。在工厂方法模式中,工厂父类负责定义创建产品对象的工接口,而工厂子类则负责生成具体的产品对象,这样做的目的是将产品类的实例化操作延迟到工厂子类中完成,即通过工厂子类来确定究竟应该实例化哪一个具体产品
2.2 结构
- Product: 抽象产品
- ConcreteProduct: 具体产品
- Factory:抽象工厂
- ConcreteFactory:具体工厂
2.3 场景案例
通过工厂方法模式实现一个计算器的程序,需要完成两个数字的加减乘除操作
计算器设计类图:
实现代码:
design_mode/src/main/java/com/nongminggong/factory/method at liuyu · constantRAIN/design_mode
客服端调用代码:
代码语言:java复制public class OperationClient {
public static void main(String[] args) {
OperationNumber operationNumber = new OperationNumber(10, 5);
// 加法
OperationFactory operationAddFactory = new OperationAddFactory();
Operation operationAdd = operationAddFactory.createOperation();
double addResult = operationAdd.operate(operationNumber);
System.out.println("加法结果" addResult);
// 减法
OperationFactory operationSubFactory = new OperationSubFactory();
Operation operationSub = operationSubFactory.createOperation();
double subResult = operationSub.operate(operationNumber);
System.out.println("减法结果" subResult);
// 乘法
OperationFactory operationMulFactory = new OperationMulFactory();
Operation operationMul = operationMulFactory.createOperation();
double mulResult = operationMul.operate(operationNumber);
System.out.println("乘法结果" mulResult);
// 除法
OperationFactory operationDivFactory = new OperationDivFactory();
Operation operationDiv = operationDivFactory.createOperation();
double divResult = operationDiv.operate(operationNumber);
System.out.println("除法结果" divResult);
}
}
执行结果:
2.4 优缺点
优点:
- 包括简单工厂的所有优点
- 遵循了开闭原则
缺点:
- 增加了类的个数,在一定程度上提升了系统的复杂度
- 客服端在使用的时候需要指定对应的工厂才能完成对象的创建
2.5 使用场景
工厂方法模式是简单工厂的一种推广和抽象,提高了工厂的扩展性
- 客服端不需要知道具体产品类的类名,只需要知道所对应的工厂即可,具体工厂就会完成具体的实例创建
- 对于抽象工厂类只需要提供一个创建产品的接口,由其子类来确定具体要创建的对象,利用面向对象的多态性和里式替换原则原则,在程序运行是,子类对象覆盖父类对象,从而是的系统更容易扩展
3. 抽象工厂模式
3.1 定义
抽象工厂模式(Abstract Factory Pattern): 提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类。抽象工厂模式又称为Kit模式,属于对象创建型模式
3.2 结构
Factory: 抽象工厂
ConcreteFactory:具体工厂
Product和Product2:抽象产品
ConcreteProdcut1和ConcreteProduct2:具体产品
3.3 场景案例
通过sqlServer和Access完成创建用户、查询用户和创建员工、查询员工的功能
场景类图:
实现代码:
design_mode/src/main/java/com/nongminggong/factory/abstracts at liuyu · constantRAIN/design_mode
客户端代码:
代码语言:java复制public class OperationClient {
public static void main(String[] args) {
AbstractFactory sqlServerFactory = new SqlServerFactory();
UserService sqlServerUser = sqlServerFactory.createUser();
sqlServerUser.insert(new User());
sqlServerUser.getUser();
DepartmentService sqlServerDepartment = sqlServerFactory.createDepartment();
sqlServerDepartment.insert(new Department());
sqlServerDepartment.getDepartment();
AbstractFactory accessFactory = new AccessFactory();
UserService accessUser = accessFactory.createUser();
accessUser.insert(new User());
accessUser.getUser();
DepartmentService accessDepartment = accessFactory.createDepartment();
accessDepartment.insert(new Department());
accessDepartment.getDepartment();
}
}
执行结果:
3.4 优缺点
优点:
- 抽象工厂模式隔离了具体类的生成,使得客户并不需要知道什么被创建。由于这种隔离,更换一个具体工厂就变得相对容易。所有的具体工厂都实现了抽象工厂中定义的那些公共接口,因此只需改变具体工厂的实例,就可以在某种程度上改变整个软件系统的行为。另外,应用抽象工厂模式可以实现高内聚低耦合的设计目的,因此抽象工厂模式得到了广泛的应用。
- 当一个产品族中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一个产品族中的对象。这对一些需要根据当前环境来决定其行为的软件系统来说,是一种非常实用的设计模式。
- 增加新的具体工厂和产品族很方便,无须修改已有系统,符合“开闭原则”。
缺点:
- 在添加新的产品对象时,难以扩展抽象工厂来生产新种类的产品,这是因为在抽象工厂角色中规定了所有可能被创建的产品集合,要支持新种类的产品就意味着要对该接口进行扩展,而这将涉及到对抽象工厂角色及其所有子类的修改,显然会带来较大的不便。
- 开闭原则的倾斜性(增加新的工厂和产品族容易,增加新的产品等级结构麻烦)。
3.5 使用场景
- 一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节,这对于所有类型的工厂模式都是重要的。
- 系统中有多于一个的产品族,而每次只使用其中某一产品族。
- 属于同一个产品族的产品将在一起使用,这一约束必须在系统的设计中体现出来。
- 系统提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于具体实现。
4 工厂模式的退化
- 当抽象工厂模式中每一个具体工厂类只创建一个产品对象,也就是只存在一个产品等级结构时,抽象工厂模式退化成工厂方法模式;当工厂方法模式中抽象工厂与具体工厂合并,提供一个统一的工厂来创建产品对象,并将创建对象的工厂方法设计为静态方法时,工厂方法模式退化成简单工厂模式。