设计模式 Day03 工厂三兄弟

1. 如何判断你已经掌握了某种设计模式?(非常重要)
  • ① 这个模式的意图是什么?它解决了什么问题、什么时候可以使用它
  • ② 它是如何解决的?掌握它的结构图,记住它的关键代码
  • ③ 至少能够想到它的两个应用实例,一个生活中的,一个软件中的
  • ④ 这个模式的缺点是什么?在使用时要注意什么

一、简单工厂模式

1. 这个模式的意图是什么?它解决了什么问题、什么时候可以使用它
  • 什么时候使用它:
  • ① 当一个产品的创建过程比较复杂,而使用者不必关心,
  • ② 并且使用者传入不同参数,能拿到不同产品实例对象时使用(达到创建和使用分离的效果)
2. 它是如何解决的?掌握它的结构图,记住它的关键代码
  • 结构图:ConcreteFactory(具体工厂角色)、Product(抽象产品角色)、ConcreteProduct(具体产品角色)
  • 关键代码:ConcreteFactory 里面有个静态方法,用 if-else 语法来 根据用户传入的参数,获取具体的对象
3. 至少能够想到它的两个应用实例,一个软件中的,一个生活中的
  • 软件中:图表展示页面,调用 ConcreteFactory 静态方法,传入参数,可根据参数获得饼图、直方图、折线图等等
  • 生活中:暂时未想到
4. 这个模式的确定是什么?在使用时要注意什么
  • 缺点:
  • ① 当返回的类型多的情况下,ConcreteFactory 的静态方法将变得臃肿,并且难以维护
  • ② 当有一个新的图形,比如环形图要加入时,需要修改 ConcreteFactory 的静态方法,不符合软件设计原则中的开闭原则
  • ③ 所有的产品实例都依赖于一个 ConcreteFactory,一旦 ConcreteFactory 不能工作,影响将会非常大

二、工厂方法模式

1. 这个模式的意图是什么?它解决了什么问题、什么时候可以使用它
  • 解决了什么问题:
  • ① 解决了简单工厂模式中,增加新产品类型时,不符合开闭设计原则的问题
  • ② 解决了简单工厂模式中,过多的产品类型时,ConcreteFactory 的静态方法会变得十分臃肿的问题
2. 它是如何解决的?掌握它的结构图,记住它的关键代码
  • 结构图:Factory(抽象工厂角色)、ConcreteFactory(具体工厂角色)、Product(抽象产品角色)、ConcreteProduct(具体产品角色)
  • 关键代码:一个 具体工厂角色 对应生产一种 具体产品角色 ;工厂和产品都有抽象类
3. 至少能够想到它的两个应用实例,一个软件中的,一个生活中的
  • 软件中:日志输出工具类的编写:可能输出到文件中、可能输出到数据库中(未来可能扩展输出到阿里云中)
  • 生活中:待补充
4. 这个模式的缺点是什么?在使用时要注意什么
  • 缺点:
  • ① 工厂方法模式中一个工厂对应一类产品,很容易导致系统中存在大量的工厂类,势必会增加系统的开销
  • ② 使用工厂方法模式会增加类的数量,从而增加代码理解的难度

三、抽象工厂模式

1. 这个模式的意图是什么?它解决了什么问题、什么时候可以使用它
  • 它解决了什么问题:
  • 它解决了工厂方法中存在的问题,每个工厂只生产一类产品,可能导致系统中存在大量的工厂类,增加程序复杂度和系统开销
  • 什么时候可以使用它:
  • 当一个工厂等级结构可以创建出属于不同产品等级结构的一个产品族中所有对象时,抽象工厂模式比工厂方法模式更为简单、更有效率。
  • 抽象工厂模式与工厂方法模式最大的区别在于:
  • 工厂方法模式针对的是一个产品等级结构,而抽象工厂模式需要面对多个产品等级结构,一个工厂等级结构可以负责多个不同产品等级结构中的产品对象的创建。
图 3 产品族与产品等级结构示意图
  • 在图 3 中,不同颜色的多个正方形、圆形和椭圆形分别构成了三个不同的产品等级结构
  • 而相同颜色的正方形、圆形和椭圆形构成了一个产品族
  • 每个形状对象都位于某个产品族,并属于某个产品等级结构
图 4 抽象工厂模式示意图
  • 每个具体工厂可以生产属于一个产品族中的所有产品,例如生产颜色相同的正方形、圆形和椭圆形,所生产的产品又位于不同的产品等级结构中。
  • 如果使用工厂方法模式,图 4 所示结构需要提供 15 个具体工厂,而使用抽象工厂模式只需要提供 5 个具体工厂,极大减少了系统中类的个数。
2. 它是如何解决的?掌握它的结构图,记住它的关键代码
  • 结构图:
  • AbstractFactory(抽象工厂):它声明了一组用于创建一族产品的方法,每一个方法对应一种产品。
  • ConcreteFactory(具体工厂):它实现了再抽象工厂中声明的创建产品的方法,生产一组具体产品,这些产品构成了一个产品族,每个产品都位于某个产品等级结构中
  • AbstractProduct(抽象产品): 它为每种产品声明接口,在抽象产品中声明了产品所具有的业务方法。
  • ConcreteProduct(具体产品):它定义了具体工厂生产的具体产品对象,实现抽象产品接口中声明的业务方法。
  • 关键代码:
  • 抽象工厂角色:
abstract class AbstractFactory {
public abstract AbstractProductA createProductA(); //工厂方法一
public abstract AbstractProductB createProductB(); //工厂方法二
……
}
  • 具体工厂角色
class ConcreteFactory1 extends AbstractFactory {
    //工厂方法一
public AbstractProductA createProductA() {
    return new ConcreteProductA1();
}
 
//工厂方法二
public AbstractProductB createProductB() {
    return new ConcreteProductB1();
}
 
……
}
3. 至少能够想到它的两个应用实例,一个生活中的,一个软件中的
  • 软件中的:换皮肤体系(可以由用户下载皮肤包,然后直接更换系统内的皮肤风格)
  • 生活中的:待思考
4. 这个模式的缺点是什么?在使用时要注意什么
  • 缺点:
  • 对于新增产品等级结构是不符合开闭原则的
  • 优点:
  • 对于新增产品族是符合开闭原则的
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容