【场景】
自从上次后,男孩(Boy)和女孩(Girl)就经常一起活动。冬天将至,男孩(Boy)想去买套冬季的运动装,女孩(Girl)陪他一起去。套装包括:上衣、裤子、鞋子(这不废话!地球人都知道!呵呵)。可以选择的有:阿迪达斯、耐克、三六一度。最后女孩(Girl)帮男孩(Boy)挑了一套“三六一度”的最新款,当然男孩(Boy)也帮女孩(Girl)买了一套一样款式的运动装。(待续……)
【需求】
无论到那个店,男孩(Boy)只要说买套装,店员总不至于只拿上衣或者裤子给男孩(Boy)或女孩(Girl)挑吧。当然也不会提供其它品牌的上衣或者裤子来组合成套装(会得话就不是品牌店了)。
【分析】
在这里男孩(Boy)要买(得到)的是运动装。也就是由上衣、裤子、鞋子三件(产品)组成的。
每个品牌店就是一个生产(创造)运动装(产品)的具体工厂。他们有共同的接口,都继承于同一抽象工厂。
这样我们可以通过实例化一个具体工厂来得到一种具体产品(到一个品牌店就可以买一整套运动装),
我们也可以通过增加具体工厂和具体产品来扩展运动装品种。
【作用意图】
提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
在这里可以理解为:男孩(Boy)要买运动装,可以到“三六一度”品牌店就可以买到该品牌的运动装。
而“三六一度”品牌店是一个实现“运动装工厂接口”的店(类)。
【使用场合】
一个系统要独立于产品类实例的创建、组合和表达的时候。(我们只关心有那些运动装品牌店,而不关心运动装是什么生产、组装的)
这个系统有多种产品系列,而系统只创建其中一种产品系列。(有多个品牌运动装,我们只买一种品牌运动装)
需要提供一个产品类库,而只想显示他们的接口,隐藏他们的实现时。
(就是提供一个运动装品牌店的抽象类、接口,中间定义每中产品的接口,但没有实现他们。)
【效果】
优点:
使产品系列容易交换,只要更换相应的具体工厂即可。(要买其它品牌的运动装,到其他的品牌店买就可以了。)
有利于产品的一致性。由抽象工厂创建的产品必须符合相同的接口。
(每个品牌店卖的运动装都是由上衣、裤子、鞋子组合的。总不至于上衣跟皮带组合吧。什么?不穿裤子也行?)
缺点:
难以支持新产品的类型。这要分两种情况,一种是增加新品牌运动装,这需要新增一个具体工厂(品牌店)和一个产品系列(新品牌运动装)。
另一种情况是,我要给运动装的定义上加上帽子也就是有四种产品组合的。这就动到抽象工厂的接口了。就不符合设计原则了。
【加深理解】
抽象工厂创建的产品系列之间要有依赖或作用的关系。(上衣、裤子、鞋子都属于运动装)
每一个具体工厂可以是静态方法或者使用单件模式。(单件模式后面会提到)
工厂方法模式:
一个抽象产品类,可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类只能创建一个具体产品类的实例。
抽象工厂模式:
多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类可以创建多个具体产品类的实例。
区别:
工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。
工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。
当抽象工厂模式只实现产生一个抽象产品类的时候就可以看做工厂方法。
【实现类图】