1、意图
    提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

2、别名
    Kit

3、适用性
    以下情况下可以使用此模式:

    • 一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节,这对于所有形态的工厂模式都是重要的。

    • 这个系统有多于一个的产品族,而系统只消费其中某一产品族。

    • 同属于同一个产品族的产品是在一起使用的,这一约束必须在系统的设计中体现出来。

    • 系统提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于实现。

4、从上一篇的例子引申出来的一个问题:
    上一篇我们说到了使用硬编码的方法创建一个迷宫。这次我们需要将上面的代码复用,来创建一个被施了魔法的迷宫,这个施了魔法的迷宫由施过魔法的房间,需要符咒才能通过的门以及普通的墙壁构成。那么我们来看抽象工厂是如何方便解决这个问题的。

5、例子的结构图示、代码及注释 
     《设计模式》学习笔记(4)——抽象工厂模式(Abstract Factory)  
  
    在这里,构建迷宫的元素在MazeFactory中创建,对应的代码如下:

《设计模式》学习笔记(4)——抽象工厂模式(Abstract Factory)namespace My.Reading.DesignPatterns.AbstractFactory
}


注意这里并没有将MazeFactory声明为abstract,因为在这个例子中,MazeFactory既作为AbstractFactory,EnchantedMazeFactory就是继承自它;同时又作为ConcreteFactory,它仍然需要创建普通的Maze对象。那么同样它的派生类的代码如下:

《设计模式》学习笔记(4)——抽象工厂模式(Abstract Factory)namespace My.Reading.DesignPatterns.AbstractFactory
}


由于Wall使用的仍然是普通的Wall,因此没有必要覆盖抽象工厂的虚方法。同时为了方便,没有使用EnchantedMaze而仍然使用Maze,只是在添加Room和Door的时候添加的是EnchantedRoom和DoorNeedingSpell。

Maze由于在上一篇已经定义过了,我们不需要改变原有的代码,我们现在只需要将与原来不同的类EnchantedRoom和DoorNeedingSpell重新定义。代码如下:

《设计模式》学习笔记(4)——抽象工厂模式(Abstract Factory)namespace My.Reading.DesignPatterns.AbstractFactory

那么,现在我们使用工厂作为参数来构建迷宫。如果我们使用普通迷宫,则传入创建普通迷宫的工厂;如果我们使用施了魔法的迷宫,则传入创建施了魔法魔法的迷宫的工厂。

《设计模式》学习笔记(4)——抽象工厂模式(Abstract Factory)namespace My.Reading.DesignPatterns.AbstractFactory
}

这样我们便避开了使用硬编码的方法,使得程序更容易扩展。

6、实现抽象工厂的一些有用技术:
    1)将工厂作为单件:一个应用中一般每个产品系列只需一个ConcreteFactory,因此工厂最好实现为一个Singleton。
    2)创建产品。抽象工厂仅仅声明了创建产品的接口,真正创建是由子类实现。那么通常有可能为每个产品定义一个工厂方法。但如果是有多个可能的产品系列,具体工厂也可以使用Phototype模式来实现。其实这样的创建产品主要是为了削弱抽象工厂对产品族的约束。
 
PS:原文是用C++描述的,很多地方只是示意性的代码。因此有些地方可能会有错误,欢迎指正。

此文章对应的代码下载:点击此处下载

相关文章:

  • 2022-12-23
  • 2022-01-10
  • 2022-12-23
  • 2021-11-12
  • 2021-07-09
  • 2022-01-06
  • 2021-11-03
  • 2022-02-26
猜你喜欢
  • 2021-12-19
  • 2021-06-06
  • 2021-06-19
  • 2021-05-29
相关资源
相似解决方案