设计模式系列(一)—简单工厂模式

​ hello各位程序员大哥大姐好,上期我讲解了设计模式的概念及分类,学习了UML类图的认识,今天我们就趁热打铁,学习一下简单工厂模式,以后每一个模式会出一篇文章,供各位及我自己查阅学习。斗图还是不能忘的,为了苟且的生活,大家加油,生活不止眼前的苟且,还有远方的苟且。

img

第一节:简单工厂模式概述

​ 简单工厂模式(Smiple Factory Pattern):定义一个工厂类,他可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类。

​ 简单理解:“工厂”二字,顾名思义工厂就是可以模式化生产某种特殊类型的产品的地方,例如一个鞋厂,客户要求生产的是运动鞋还是休闲鞋还是皮鞋,工厂根据要求生产出具体的鞋子的产品,但是不管是哪种鞋子,它的种类都属于“鞋子”,客户提出的要求就是“参数不同”,返回不同的实例就是厂子生产后交付的产品不同,被创建的实例通常有共同的父类就更好理解了,就是无论是什么鞋子,它的分类都是“鞋子”;

img

第二节:简单工厂模式的结构

简单工厂模式的结构包含如下三个角色:

(1)工厂角色(Factory):工厂角色即工厂类,他是简单工厂模式的核心,负责创建所有产品实例的内部逻辑;工厂类可以被外界直接调用,创建所需要的产品对象;在工厂类中提供进后台的工厂方法factoryMethod(),它返回的产品类型为抽象的产品类型Product;类似于第一节的“鞋厂”角色。

(2)抽象产品角色(Product):它是工厂类创建的所有对象的父类,封装了各种产品对象的公有方法,它的引入提高了系统的灵活性,使得在工厂类中只需要定义一个通用的工厂方法,因为所有创建的具体产品都是其子类对象;类似与第一节中的“鞋”类。

(3)具体产品角色(ConcreteProduct):它是简单工厂的创建目标,所有被创建的对象都充当这个角色的某个具体类的实例。每一个具体产品角色都集成了抽象产品角色,需要在实现在抽象产品中声明的抽象方法。

简单工厂模式类图:

img

简单工厂模式的实现流程:

​ 首先将需要创建的各种不同对象的相关代码封装到不同的类中,这些类称为具体产品类,而将它们的公共的代码进行抽象和提取后,封装在一个抽象产品中,每一个具体产品都是抽象产品的子类;然后提供一个工厂类用于创建各种产品,在工厂类中提供一个创建产品的工厂方法,该方法可以根据传入的参数不同创建不同的具体产品对象;客户端只需要调用工厂类的工厂方法并传入响应的参数即可得到一个具体产品对象。

简单工厂模式的代码实现

1.定义抽象产品

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package com.yang.easyfactory;

/**
* @ClassName Product
* @Description 抽象产品类
* @Author IT小白架构师之路
* @Date 2020/12/6 15:39
* @Version 1.0
**/
public abstract class Product {
/**
* 所有产品的公共业务方法
*/
public void publicMethod(){
System.out.println("我是公用方法");
}
//所有产品都需要实现的的业务方法
public abstract void method();

定义具体产品类A:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.yang.easyfactory;

/**
* @ClassName ConcreteProductA
* @Description 具体产品
* @Author IT小白架构师之路
* @Date 2020/12/6 15:46
* @Version 1.0
**/
public class ConcreteProductA extends Product{
@Override
public void method() {
System.out.println("我是产品");
}
}

定义具体产品类B:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.yang.easyfactory;

/**
* @ClassName ConcreteProductB
* @Description 具体产品
* @Author IT小白架构师之路
* @Date 2020/12/6 15:46
* @Version 1.0
**/
public class ConcreteProductB extends Product{
@Override
public void method() {
System.out.println("我是产品B");
}
}

定义工厂类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package com.yang.easyfactory;

/**
* @ClassName Factory
* @Description 工厂类
* @Author IT小白架构师之路
* @Date 2020/12/6 15:50
* @Version 1.0
**/
public class Factory {
/**
* 静态工厂方法
* @param arg
* @return
*/
public static Product getProduct(String arg){
//定义返回值
Product product = null;
if("A".equals(arg)){
//初始化为A
product = new ConcreteProductA();
}else if("B".equals(arg)){
//初始化为B
product = new ConcreteProductB();
}
return product;
}
}

编写客户端测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package com.yang.easyfactory;

/**
* @ClassName Client
* @Description 客户端
* @Author IT小白架构师之路
* @Date 2020/12/6 15:56
* @Version 1.0
**/
public class Client {
public static void main(String[] args) {
Product product;
//通过工厂类创建具体产品对象
product = Factory.getProduct("A");
product.publicMethod();
product.method();
}
}

6.测试结果如下:

1
2
我是公用方法 
我是产品A

第四节:

简单工厂模式的优缺点分析及适用场景

优点:

(1)工厂类包含必要的判断逻辑,可以决定在什么时候创建哪一个产品类的实例,客户端可以免除直接创建产品对象的职责,而仅仅“消费”产品,简单工厂模式实现了对象创建和使用的分离。

(2)客户端无须知道所创建的具体产品类的类名,只需要具体产品类所对应的参数即可,使用抽象产品接收即可使用具体方法,也减少了对某些复杂类名的记忆。

(3)可以在客户端引入配置文件,将参数与具体产品类进行关联,这样客户端就可以不修改代码的情况下增加新的具体产品类,可提高系统的灵活性。

缺点:

(1)由于工厂类集中了所有产品的创建逻辑、职责过重,一旦不能正常工作,整个系统则不能正常运转。

(2)使用简单工厂模式势必会增加系统中类的个数,增加了系统的复杂度和理解难度。

(3)系统扩展困难,一旦添加新的产品,就要修改工厂模式逻辑,在产品较多时会造成工厂逻辑过于复杂,不利于系统的扩展和维护。

(4)简单工厂模式使用了静态工厂方法,工厂无法形成基于继承的等级结构(不能使用泛化)。

适用场景:

(1)工厂类负责创建的对象比较少时,此时不会造成工厂方法的业务逻辑太过复杂。

(2)客户端只知道传入工厂类的参数,对于如何创建对象并不会关心。