转自:《Java 设计模式》2009年( 耿祥义 张跃平 著)
一,概括
抽象工厂模式(别名:配套)
提供一个创建一系列或相互依赖对象的接口,而无需指定他们具体的类
二,引入
设计某些系统是可能需要为用户提供一系列相关的对象,但系统不希望用户直接使用 new运算符 实例化这些对象,而是应由系统控制这些对象的创建。否则用户不仅要知道用哪些类来创建对象,而且还必须清楚这些对象之间是怎么相关的,使得用户的代码与这些类形成耦合,不利于维护。
比如:商家要去工厂采购衣服裤子,这些商家自然不能自己生产衣服(直接使用 new运算符 实例化这些对象,用哪些类来创建对象).这些商家只能来到特定的工厂,他们自然会提供给你提供他们品牌的衣服。其中这些工厂是有生产配套的衣服和裤子的,商家也无需事先了解哪些衣服和裤子是一套的(对象之间是怎么相关的),工厂直接就提供给你一整套的衣物,这些衣物配套生产,这些商家也无法单独购买。商家只需要对工厂提供给你的样品衣物中做出选择,是否购买。
三,代码与类图
衣服有两种衣服,江牌风衣和鸟牌衬衫;裤子有两种裤子,江牌牛仔裤和鸟牌裙子;工厂有两座,一个是江牌的工厂。一个是鸟牌的工厂。
package MM; /************************* Clothes *************************/ abstract class Clothes { abstract public int getChestSize(); abstract public int getHeight(); abstract public String getName(); } class WindCoat extends Clothes { public int getChestSize() { return 90; } public int getHeight() { return 175; } public String getName() { return "江牌风衣"; } } class Shirt extends Clothes { public int getChestSize() { return 90; } public int getHeight() { return 170; } public String getName() { return "鸟牌衬衫"; } } /************************* Pants *************************/ abstract class Pants { abstract public int getWaistSize(); abstract public int getHeight(); abstract public String getName(); } class Jeans extends Pants { public int getWaistSize() { return 75; } public int getHeight() { return 175; } public String getName() { return "江牌牛仔裤"; } } class Skirt extends Pants { public int getWaistSize() { return 62; } public int getHeight() { return 170; } public String getName() { return "鸟牌裙子"; } } /************************* Factory *************************/ abstract class Factory { public Factory() { System.out.printf("生产了一套衣物: "); System.out.printf(createClothes().getName() + ": "); System.out.printf("*胸围:" + createClothes().getChestSize() + " "); System.out.printf("*身高:" + createPants().getHeight() + " "); System.out.printf(createPants().getName() + ": "); System.out.printf("*腰围:" + createPants().getWaistSize() + " "); System.out.printf("*身高:" + createPants().getHeight() + " "); System.out.printf(" "); } abstract public Clothes createClothes(); abstract public Pants createPants(); } class JiangFactory extends Factory { public Clothes createClothes() { return new WindCoat(); } public Pants createPants() { return new Jeans(); } } class NiaoFactory extends Factory { public Clothes createClothes() { return new Shirt(); } public Pants createPants() { return new Skirt(); } } public class M { public static void main(String L[]) { Clothes c; Pants p; Factory f; f = new JiangFactory(); c = f.createClothes(); p = f.createPants(); f = new NiaoFactory(); c = f.createClothes(); p = f.createPants(); } }
类图:
(注: 由于找不到合适的箭头,这箭头就画的不标准了)
四,工厂方法模式的结构
① 抽象产品(Product): Clothes类 和 Pants类
② 具体产品(ConcreteProduct): WindCoat类 和 Shirt类 和 Jeans类 和 Skirt类
③ 抽象工厂(Creator): Factory类
④ 具体工厂(ConcreteCreator): JiangFactory1类 和 NiaoFactory类
五,抽象工厂模式的优缺点
优点:
① 抽象工厂模式可以为用户创建一系列相关的对象,使用户和创建这些对象的类脱耦。
② 用户使用不同的具体工厂就能得到一组相关的对象,可以避免用户混用不同系列中的对象。
③ 在抽象工厂模式中,可以随时增加 “具体工厂”,为用户提供一组相关的对象。
缺点:一旦原有的实体类进行扩充,就无法正常工作,(如在上述例子中,还要给 江牌 的套装增加一双袜子,就必须修改抽象工厂的代码了)
六,抽象工厂模式的使用场景
① 系统需要为用户提供多个对象,又希望用户和创建对象的类脱耦。
② 系统需要为用户提供多个相关的对象,当又不希望用户决定这些对象是如何关联的。
③ 系统需要用户提供一系列对象,用户只需要知道有这些对象有哪些方法可用,不需要知道这些对象的创建过程。
七,抽象工厂模式的使用
用户在使用抽象工厂模式时,只和抽象产品,抽象工厂以及具体构工厂打交道,用户只需了解抽象产品有哪些方法,不需要知道有哪些具体产品。
抽象工厂方法模式的关键是 在一个接口或抽象类中定义若干个 抽象方法(抽象工厂),这些方法分别返回某个类的子类的实例,该抽象类或接口 让其 子类或实现该接口的类(具体工厂) 通过重写这些抽象方法 为用户提供一系列相关的对象
=========== ========= ======== ======= ===== ==== === == =
蝶恋花 宋代: 柳永
拟把疏狂图一醉,对酒当歌,强乐还无味。