当前位置:   article > 正文

工厂设计模式总结

工厂设计模式总结

一、简单工厂

1.1 概述

背景: 代码中存在根据不同条件创建不同对象的场景。例如:

if ("json".equals(name)) {
     return new JsonConfigParser();
} else if ("xml".equals(name)) {
     return new XmlConfigParser();
} else if ("yaml".equals(name)) {
     return new YamlConfigParser();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

存在的问题:

  • 当需要增加新的对象时,需要直接修改代码,违背了开闭原则;
  • 对象的创建和使用耦合在一块,耦合性强,违背了面向接口编程;
  • 创建和使用在同一个方法中,违背了方法的单一职责原则,若方法逻辑复杂,则会导致可读性下降

解决方案: 使用简单工厂。抽象出一个Factory类,负责对象的创建,并提供给外部使用的方法。

1.2 定义

 提供一个创建对象实例的功能,而无需关心其具体实现。被创建实例的类型可以是接口、抽象类或普通类。
  • 1

1.3实现方案

多例场景下:所有对象抽象出一层Factory对象,但中间的if…else逻辑没有去掉,修改时违背了开闭原则
单例场景:使用Map提前缓存单例对象。

1.4 优缺点

优点:

1. 封装性好。对创建对象的行为封装了一层Factory类,实现了面向接口编程;
2. 松耦合。将对象创建和使用解耦,实现了松耦合;
3. 可维护性好。将创建对象的行为统一到Factory类中,实现【一处修改,多处联动】,维护性大大提高;
4. 符合单一职责。将创建对象的行为放到Factory类中,实现了Factory类的职责单一。
  • 1
  • 2
  • 3
  • 4

缺点:

1. 客户端需要知道传入的参数是什么含义,才能准确创建对象,增加了复杂度;
2. 若需要新增加对象的类型,需要修改Factory类中的if..else逻辑,违背了开闭原则
  • 1
  • 2

二、工厂方法

2.1 背景

主要解决简单工厂模式下的多例场景中的if…else问题,使修改代码符合开闭原则。

2.2 定义

定义一个用于创建对象的接口,让子类决定实例化哪一个类,使一个类的实例化延迟到其子类中。
  • 1

2.3 实现方案

方案1:使用多态的方式,针对每一个对象,单独创建一个工厂类,但是在使用端又引入了if…else来判断使用哪个Factory类
优化方案:Factory一般场景下是单例的,考虑使用Map来进行缓存【SpringBoot中可以使用@PostConstuct注解实现无缝注入】

2.4 优缺点

优点:

1. 符合开闭原则
  • 1

缺点:

1. 增加了类的个数,降低了可读性
  • 1

三、抽象工厂

背景: 简单工厂和工厂方法解决的是单一维度的分类方式。比如按照颜色给水果进行分类,但是若新增分类方式,按照品种进行分类,则需要创建一倍的工厂对象,增加了系统复杂度。
解决方案: 一个工厂对象可以创建不同类型的对象,可以有效降低工厂对象的个数。

四、三种实现方式的应用场景

4.1 按照维度来区分

单一维度:采用简单工厂或工厂方法模式
多维度:采用抽象工厂模式

4.2 简单工厂和工厂方法模式区分

  1. 如果每个Factory仅做简单的new对象操作,会导致Factory层非常薄,考虑采用简单工厂方式
  2. 若创建对象的逻辑比较复杂,比如中间要组合其他类对象,做各种初始化操作的时候,考虑采用工厂方法模式

某些场景下: 如果对象不可复用,那工厂类每次都要返回不同的对象。如果我们使用简单工厂模式来实现,就只能选择第一种包含 if 分支逻辑的实现方式。如果我们还想避免烦人的 if-else 分支逻辑,这个时候,我们就推荐使用工厂方法模式

五、收获

  1. 封装变化】:要识别出【稳定点和非稳定点】,将非稳定点进行约束,即要考虑扩展,使用设计模式进行优化。比如工厂模式,稳定点是调用方使用方式,非稳定点是对象的创建逻辑,因此,将创建逻辑给抽取出来
  2. 代码复用】:项目中很多地方使用相同的逻辑,那么需要抽取通用的逻辑出来进行封装。比如工厂模式,创建对象的动作可能散落在各个地方,使用工厂模式可以统一管理,达到代码复用;
  3. 隔离复杂性】:将复杂的逻辑封装起来,调用者可以不关系复杂逻辑的过程;
  4. 控制复杂度】:将复杂的逻辑抽离出来,让原本的函数职责更加单一,代码更加简洁。比如工厂模式,将创建逻辑抽取到Factory类中
声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
  

闽ICP备14008679号