首页 > 其他 > 详细

案例分析:设计模式与代码的结构特性

时间:2019-12-08 20:08:18      阅读:78      评论:0      收藏:0      [点我收藏+]

1.抽象工厂模式是什么

  工厂模式分为三种,简单工厂模式,工厂方法模式,以及抽象工厂模式。

  简单工厂模式实例化对象的时候不再使用 new Object()形式,可以根据用户的选择条件来实例化相关的类。对于客户端来说,去除了具体的类的依赖。只需要给出具体实例的描述给工厂,工厂就会自动返回具体的实例对象。

  而工厂方法模式是对简单工厂模式进一步的解耦,因为在工厂方法模式中是一个子类对应一个工厂类,而这些工厂类都实现于一个抽象接口。这相当于是把原本会因为业务代码而庞大的简单工厂类,拆分成了一个个的工厂类,这样代码就不会都耦合在同一个类里了。

  前面介绍的工厂方法模式中考虑的是一类产品的生产,同种类称为同等级,也就是说:工厂方法模式只考虑生产同等级的产品,但是在现实生活中许多工厂是综合型的工厂,能生产多等级(种类) 的产品。简而言之,抽象工厂模式是用来生产不同产品族的全部产品。(对于增加新的产品,无能为力; 支持增加产品族),抽象工厂模式是工厂方法模式的升级版本,在有多个业务品种、业务分类时,通过抽象工厂模式产生需要的对象是一种非常好的解决方式。

2.抽象工厂模式的应用场景

  当出现一系列的产品族,且这些类比较容易划分时,设计模式可以采用使用抽象工厂模式。原因如下:若使用简单工厂模式,那么一个工厂任务会过于繁重(要产生很多类),且各个类间区分度不高;而若使用工厂函数模式,每个类对应一个新的工厂,此时需要创建太多类了,代码冗杂,不利于维护;最好的办法就是现根据现有类的信息对其进行分组处理,然后每组由一个工厂类去完成,这样既体现了一对一的定制服务(分组)又体现了工厂的集中生产(每一个工厂生产一类)。

  • 系统中有多个产品族,每个具体工厂创建同一族但属于不同等级结构的产品。
  • 系统一次只可能消费其中某一族产品,即同族的产品一起使用。

抽象工厂模式

  • 当涉及到产品族的时候,就需要引入抽象工厂模式了。
  • 一个经典的例子是造一台电脑。我们先不引入抽象工厂模式,看看怎么实现。
  • 因为电脑是由许多的构件组成的,我们将 CPU 和主板进行抽象,然后 CPU 由 CPUFactory 生产,主板由 MainBoardFactory 生产,然后,我们再将 CPU 和主板搭配起来组合在一起,如下图:

技术分享图片

  • 这个时候的客户端调用是这样的:
// 得到 Intel 的 CPU
CPUFactory cpuFactory = new IntelCPUFactory();
CPU cpu = intelCPUFactory.makeCPU();

// 得到 AMD 的主板
MainBoardFactory mainBoardFactory = new AmdMainBoardFactory();
MainBoard mainBoard = mainBoardFactory.make();

// 组装 CPU 和主板
Computer computer = new Computer(cpu, mainBoard);
  • 单独看 CPU 工厂和主板工厂,它们分别是前面我们说的工厂模式。这种方式也容易扩展,因为要给电脑加硬盘的话,只需要加一个 HardDiskFactory 和相应的实现即可,不需要修改现有的工厂。

  • 但是,这种方式有一个问题,那就是如果** Intel 家产的 CPU 和 AMD 产的主板不能兼容使用**,那么这代码就容易出错,因为客户端并不知道它们不兼容,也就会错误地出现随意组合。

-下面就是我们要说的产品族的概念,它代表了组成某个产品的一系列附件的集合:

技术分享图片

  • 当涉及到这种产品族的问题的时候,就需要抽象工厂模式来支持了。我们不再定义 CPU 工厂、主板工厂、硬盘工厂、显示屏工厂等等,我们直接定义电脑工厂,每个电脑工厂负责生产所有的设备,这样能保证肯定不存在兼容问题。

技术分享图片

  • 这个时候,对于客户端来说,不再需要单独挑选 CPU厂商、主板厂商、硬盘厂商等,直接选择一家品牌工厂,品牌工厂会负责生产所有的东西,而且能保证肯定是兼容可用的。
public static void main(String[] args) {
    // 第一步就要选定一个“大厂”
    ComputerFactory cf = new AmdFactory();
    // 从这个大厂造 CPU
    CPU cpu = cf.makeCPU();
    // 从这个大厂造主板
    MainBoard board = cf.makeMainBoard();
      // 从这个大厂造硬盘
      HardDisk hardDisk = cf.makeHardDisk();

    // 将同一个厂子出来的 CPU、主板、硬盘组装在一起
    Computer result = new Computer(cpu, board, hardDisk);
}
  • 当然,抽象工厂的问题也是显而易见的,比如我们要加个显示器,就需要修改所有的工厂,给所有的工厂都加上制造显示器的方法。这有点违反了对修改关闭,对扩展开放这个设计原则。

案例分析:设计模式与代码的结构特性

原文:https://www.cnblogs.com/gfsh/p/12006820.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!