简单工厂模式
介绍
定义
简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现。 —— 百度百科
结构
如上图,简单工厂模式包含以下三种角色:
Product:产品
该类是抽象类,为所有产品的抽象父类,它描述了所有产品应有的公共接口
ConcreteProduct:具体产品
该类是抽象父类的具体实现,它定义了每个产品的独立使用方法
Factory:工厂
该类负责生产产品,也就是提供各个产品的创建方法
特点
- 需要创建的对象较少
- 根据自定不同参数即可创建不同对象,屏蔽了内部细节
应用
产品类
我们定义抽象产品为“动物”,动物都会发声,因此代码如下:
1 | public abstract class Animal { |
具体产品类
我们定义具体产品为”猫” “狗”,并继承动物的抽象类,如下:
猫:
1 | public class Cat extends Animal { |
狗:
1 | public class Dog extends Animal { |
工厂类
我们定义工厂可以生产出这些动物,代码如下:
1 | public class Factory { |
其中Factory.create(NAME_CAT)
就是“简单工厂模式”的核心方法。
总结
优点
- 客户端无需知道具体产品的内部细节,只需知道生产产品的名字即可生产,实现了消费和生产的解耦
- 通过配置,可以在不修改客户端的情况下修改或新增具体产品类,提高了灵活性
缺点
- 工厂类集中了所有产品的创建逻辑,比较臃肿
- 违背“开放-关闭 原则”,一旦添加新产品就必须要修改工厂类逻辑
- 工厂类使用了静态方法,不能被继承和重构,不利于后续扩展
优化
由于该模式下,工厂类包含了所有实例的创建逻辑,违反了高内聚职责分配原则,当具体产品类不断增多的时候,工厂类的单一逻辑就显得臃肿而复杂。所以我们引入了工厂方法模式。
工厂方法模式
介绍
定义
工厂方法模式(Factory method pattern)是一种实现了“工厂”概念的面向对象设计模式。就像其他创建型模式一样,它也是处理在不指定对象具体类型的情况下创建对象的问题。
工厂方法模式的实质是“定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类。工厂方法让类的实例化推迟到子类中进行。
——维基百科
结构
如上图,工厂方法模式包含以下四种角色:
Product:产品
该类是抽象类,为所有产品的抽象父类,它描述了所有产品应有的公共接口
ConcreteProduct:具体产品
该类是抽象父类的具体实现,它定义了每个产品的独立使用方法
Factory:工厂
该类是抽象类,为所有工厂的抽象父类,它描述了所有工厂应有的公共接口
ConcreteFactory:具体工厂
该类是抽象父类的具体实现,它负责生产产品,也就是提供产品的创建方法
###特点
工厂类不再负责所有产品的创建,而是拓展子类,将具体的创建工作分发给不同的子类,即允许在不修改工厂角色的情况下新增产品
封装了产品细节,只需知道具体工厂即可创建所需产品
符合『开放-封闭原则』
应用
产品类
我们定义产品类为动物,动物都会发声,因此代码如下:
1 | public abstract class Animal { |
具体产品类
我们在这里创建两个品种的动物,分别是:
1 | public class OrangeCat extends Animal { |
工厂类
我们定义抽象的工厂类,提供一个公共接口create()
:
1 | public abstract class Factory { |
具体工厂类
有了工厂类的公共接口后,我们即可拓展出自己细分的工厂,如CatFactory
和DogFactory
:
1 | public class CatFactory extends Factory { |
创建好了这些单独工厂和产品之后,我们即可以方便地使用了:
1 | public class Main { |
打印如下:
1 | 喵喵喵 |
总结
优点
- 工厂方法创建了用户所需的产品,且隐藏了具体实例化的细节,用户只需关心工厂,而无需关心具体的创建细节
- 具有多态的特性,所有工厂都由同一抽象父类拓展而成
- 加入新产品时,无需修改抽象接口或父类,只需添加一个具体工厂和产品即可
缺点
- 添加新产品时,对应要添加新的具体工厂类,代码量较多
- 抽象层较多,增加了系统的复杂度
###优化
抽象工厂模式
介绍
定义
结构
特点
应用
当具体产品类较多时,抽象工厂模式就派上用场了,比如我们在这里创建两种类别,四个品种的动物,分别是:
猫 | 狗 |
---|---|
BritishCat | GermanDog |
OrangeCat | GlodenDog |
我们先定义由 Animal
拓展而出的 Cat
,Dog
抽象类:
1 | public abstract class Cat extends Animal {} |
再定义“具体产品”,也就是四种不同动物的品种:
1 | public class BritishCat extends Cat { |
工厂类
我们定义抽象的工厂类,提供一个公共接口create()
:
1 | public abstract class Factory { |
具体工厂类
有了工厂类的公共接口后,我们即可拓展出自己细分的工厂,如CatFactory
和DogFactory
:
1 | public class CatFactory extends Factory { |
1 | public class DogFactory extends Factory { |
创建好了这些工厂和产品之后,我们既能方便使用,又能轻松拓展了:
1 | public class Main { |
打印如下:
1 | 喵喵喵 |
总结
优点
缺点
优化
参考链接:https://design-patterns.readthedocs.io/zh_CN/latest/creational_patterns/creational.html
https://www.jianshu.com/p/83ef48ce635b
https://www.hollischuang.com/archives/1391