设计模式之工厂三兄弟

2022-11-28 10:05:22 浏览数 (2)

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 工厂模式的退化

  • 当抽象工厂模式中每一个具体工厂类只创建一个产品对象,也就是只存在一个产品等级结构时,抽象工厂模式退化成工厂方法模式;当工厂方法模式中抽象工厂与具体工厂合并,提供一个统一的工厂来创建产品对象,并将创建对象的工厂方法设计为静态方法时,工厂方法模式退化成简单工厂模式。

0 人点赞