抽象工厂模式

内容参考:http://www.cnblogs.com/java-my-life/archive/2012/03/28/2418836.html

请先看上面那位大牛的博客,以下只是对上面博客的一些个人理解和简化

注意:大部分都是抄的,自己再写一个,只是想加深自己的印象。

简单工厂模式

以电脑组装为例,使用简单工厂模式来实现,定义cpu,主板……等配件的工厂来实例对应的对象,然后使用。

** 问题 **

  • 如果组装电脑时用错了工厂方法,比如创建了一个intelcpu,amd主板,这样组装的电脑肯定时错误的,也是无法组装成功的

那如何规避这种问题呢,就要引入接下来的抽象工厂模式

在学习抽象工厂之前,引入两个概念:产品族产品等级

产品族是指位于不同产品等级结构中,功能相互关联的产品组成的家族,比如:AMD的主板+CPU+芯片组 组成一个AMD产品族,而 Intel的主板+CPU+芯片组 组成一个Intel 的产品族。这两个产品族都来自与三个产品等级 主板、芯片组、CPU

上面所给出的三个不同的等级结构具有平行的结构。因此,如果采用工厂方法模式,就势必要使用三个独立的工厂等级结构来对付这三个产品等级结构。由于这三个产品等级结构的相似性,会导致三个平行的工厂等级结构。随着产品等级结构的数目的增加,工厂方法模式所给出的工厂等级结构的数目也会随之增加,如下图

那么,是否可以使用同一个工厂等级结构来应付这些相同或者极为类似的产品等级结构呢? 这也就是抽象工厂模式的好处,同一个工厂等级结构负责三个不同产品等级结构中的产品对象的创建

可以看出,一个工厂等级结构可以创建出分属不同产品等级的同一个产品族中的所有对象,显然 这时候抽象工厂模式 比简单工厂模式、工厂方法模式更有效率,对应的每一个产品族都有一个具体的工厂,而每个工厂负责创建属于同一个产品族,但 分属不同等级结构的产品,同时也规避了 使用产品族 内 产品等级不一致的问题。

抽象工厂模式结构

抽象工厂模式是对象的创建模式,他是工厂方法模式的进一步推广。

假设一个子系统需要一些产品对象,而这些产品又属于一个以上的产品等级结构。那么为了将消费这些产品对象的责任和创建这些产品对象的责任分割开来,可以引进抽象工厂模式。这样的话,消费产品的一方不需要直接参与产品的创建工作,只需要向一个公用的工厂接口请求所需的产品就可以了。

通过使用抽象工厂模式,可以处理具有相同或相似等级结构中的多个产品对象的创建问题, 例如:

由于这两个产品族的等级结构相同,因此使用同一个工厂族也可以处理这两个产品的创建问题,这就是抽象工厂模式

根据产品的结构图,可以给出工厂角色的结构设计图

代码地址

抽象工厂的功能是为一系列相关对象或者相互依赖的对象创建一个接口,需要注意的是,这个接口内的方法不是任意堆砌的,而是一系列相关或相互依赖的方法,比如:上面我们说的例子总的 主板+CPU+芯片组,都是为了组装一台可以使用的电脑 而相关联的对象,不同的装机方法,代表了一种具体的电脑系列

** 由于抽象工厂定义的一系列对象通常是相关或相互依赖的,这些产品对象一起构建了一个产品族,也就是抽象工厂定义了一个产品族的接口 **

** 这样就带来了非常不错的灵活性,当需要切换产品族时,只要提供不同的抽象工厂实现就可以了,也是就是只要切换不同的抽象工厂实现,整个产品族就作为一个整体切换了 **

在什么情况下应当使用抽象工厂模式

  • 一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节,这对于所有形态的工厂模式都是重要的(???如何理解)
  • 系统的产品有多于一个的产品族,而系统只消费其中某一族的产品(???如何理解)
  • 同属于同一个产品族的产品是在一起使用的,这一约束必须在系统的设计中体现出来(比如:CPU+主板+芯片组)
  • 系统提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于实现

抽线工厂模式的起源

抽线工厂模式的起源,是用于创建分属于不同操作系统的视窗构建。比如:btn 和 Text 文字框 都是视窗的控件,在unix系统的视窗环境 和 windows 系统的视窗环境中,这两个控件有不同的本地实现,他们的实现细节是有所不同的。

在每个操作系统中,都有各自的产品构建族,也就是 由 btn 和 Text 等组件组成的产品族,而每个组件又有 各自的产品等级 由一个抽象的角色 给出 抽象的功能描述,而子类给出 不同系统下的 产品实现

从上面的图 我们发现有两个产品等级结构,而这两个产品等级的 分属于两个产品族,也就是UNIX和windows,结合上面组装电脑的例子,我们需要设计两个工程角色,既UnixFactory和WindowsFactory,这两个对象负责创建各自产品族中的产品,同时我们也可以使用抽象工厂模式来设计,解决方案如下:

抽象工厂模式的有点

  • 分离接口和实现

    客户端使用抽象工厂来创建需要的对象,而客户端根本就不知道具体的实现是谁,客户端只是面向产品的接口编程而已。也就是说,客户端从具体产品的实现中解耦。

  • 使切换产品族变得容易

    因为一个具体的工厂实现代表的是一个产品族,比如组装电脑的例子,我们从intel切换到amd只需要切换一下具体工厂的实现。

抽象工厂模式的缺点

  • 不太容易扩展新的产品

    如果需要给整个产品族添加一个新的产品等级,那么就需要修改抽象工厂,这也就会导致所有的抽线工厂的实现类都要改。

个人总结

抽象工厂模式对于工厂方法,简单工厂的进一步扩展,对于有相同或相似产品等级 组成的产品族 进一步抽象出抽象的工厂,不同的产品族实现 抽象工厂,调用各自的产品等级实现,创建各自的产品对象,方便快速的切换,是的客户端从产品族中的产品等级中解耦出来,客户端不需要关注产品创建的细节,只需要关注产品对象即可,但是也有缺点,如果产品族中也添加新的产品,也就是抽象工厂中要添加新的抽象方法,你懂的,每个产品族的实现都要改。

转载于:https://my.oschina.net/u/2699666/blog/2209384

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值