【设计模式】抽象工厂模式
使用频率:★★★★★
一、什么是抽象工厂模式
就是对一组具有相同主题的工厂进行封装(维基百科解释的很到位);
例如:生产一台PC机,使用工厂方法模式的话,一般会有cpu工厂,内存工厂,显卡工厂...但是使用抽象工厂模式的话,只有一个工厂就是PC工厂,但是一个PC工厂涵盖了cpu工厂,内存工厂,显卡工厂等要做的所有事;
二、补充说明
- 注意这里的“相同主题”的概念,表示的是同一个产品族,不能将cpu工厂,面粉工厂封装成一个工厂,因为他们不属于同一个产品族;
- 另外,还有一个产品等级的概念,还是以生产PC机为例,所谓的产品等级指的是不同厂商生产的CPU,如Intel和AMD的CPU,他们是同一个产品等级,如果只涉及产品等级的话,是不需要应用抽象工厂模式,使用工厂方法模式即可;
- 工厂方法模式解决的范畴是产品等级(AMD处理器,Intel处理器等);抽象工厂模式解决的范畴是产品族等级(联想PC、惠普PC等);
三、角色
- 抽象工厂
- 具体工厂
- 抽象产品
- 具体产品
- 产品使用者
说明:
- 具体工厂“继承”抽象工厂;
- 具体产品”继承“抽象产品;
- 每个具体工厂(如PC工厂)包含若干个子工厂方法(如cpu工厂方法、显卡工厂方法...),子工厂方法负责生产对应的具体子产品,所有具体子产品(cpu、内存、显卡...)组合成一个具体产品(如惠普XXX型号PC);
- 产品使用者使用每个具体工厂生产的具体产品;
四、例子
这里就不用PC这个例子了,继续前一个工厂模式的例子,在上一篇工厂模式的例子中,我们使用的是创建父亲对象这个例子,其中中国父亲和美国父亲指的就是同一个产品等级;
但是当我们要创建一个家庭对象的时候,需要创建父亲对象、母亲对象、孩子对象等等,所谓的父亲、母亲、孩子就构成了一个产品族,中国家庭、美国家庭就是产品族等级;这个时候就需要使用抽象工厂模式了;
类之间的关系图:
代码实现:
先创建抽象产品(抽象母亲、抽象父亲),具体产品(具体母亲、具体父亲):
package com.pichen.dp.creationalpattern.abstractfactory; public interface IMother { public void printName(); }
package com.pichen.dp.creationalpattern.abstractfactory; public interface IFather { public void printName(); }
package com.pichen.dp.creationalpattern.abstractfactory; public class ChineseMother implements IMother{ private String name; public ChineseMother(String name) { this.name = name; System.out.println("create a cn mother."); } /** * @return the name */ public String getName() { return name; } /** * @param name the name to set */ public void setName(String name) { this.name = name; } @Override public void printName() { System.out.println(this.getClass().getName() + ":" + this.name); } }
package com.pichen.dp.creationalpattern.abstractfactory; public class AmericanMother implements IMother{ private String name; public AmericanMother(String name) { this.name = name; System.out.println("create a us mother."); } /** * @return the name */ public String getName() { return name; } /** * @param name the name to set */ public void setName(String name) { this.name = name; } @Override public void printName() { System.out.println(this.getClass().getName() + ":" + this.name); } }
package com.pichen.dp.creationalpattern.abstractfactory; public class ChineseFather implements IFather{ private String name; public ChineseFather(String name) { this.name = name; System.out.println("create a cn father."); } /** * @return the name */ public String getName() { return name; } /** * @param name the name to set */ public void setName(String name) { this.name = name; } @Override public void printName() { System.out.println(this.getClass().getName() + ":" + this.name); } }
package com.pichen.dp.creationalpattern.abstractfactory; public class AmericanFather implements IFather{ private String name; public AmericanFather(String name) { this.name = name; System.out.println("create a us father."); } /** * @return the name */ public String getName() { return name; } /** * @param name the name to set */ public void setName(String name) { this.name = name; } @Override public void printName() { System.out.println(this.getClass().getName() + ":" + this.name); } }
创建一个抽象家庭工厂接口:
package com.pichen.dp.creationalpattern.abstractfactory; /** * * abstract factory * father + mother + sister + ... = Product Family * cnfather + usfather + ukfather + ... = Product grade //factory method * 〈功能详细描述〉 * @author pi chen * @version cp-lib V1.0.0, 2015年11月25日 * @see * @since cp-lib V1.0.0 */ public interface IFamilyFactory { public IFather createFather(String name); public IMother createMother(String name); }
分别创建具体的中国家庭工厂和美国家庭工厂:
package com.pichen.dp.creationalpattern.abstractfactory; public class ChineseFamilyFactory implements IFamilyFactory{ @Override public IFather createFather(String name) { return new ChineseFather(name); } @Override public IMother createMother(String name) { return new ChineseMother(name); } }
package com.pichen.dp.creationalpattern.abstractfactory; public class AmericanFamilyFactory implements IFamilyFactory{ @Override public IFather createFather(String name) { return new AmericanFather(name); } @Override public IMother createMother(String name) { return new AmericanMother(name); } }
创面产品使用者main方法:
package com.pichen.dp.creationalpattern.abstractfactory; public class Main { public static void main(String[] args) { IFamilyFactory cnFamilyFactory = new ChineseFamilyFactory(); IFamilyFactory usFamilyFactory = new AmericanFamilyFactory(); IFather cnFather = cnFamilyFactory.createFather("cn father-test"); IMother cnMother = cnFamilyFactory.createMother("cn mother-test"); IFather usFather = usFamilyFactory.createFather("us father-test"); IMother usMother = usFamilyFactory.createMother("us mother-test"); cnFather.printName(); cnMother.printName(); usFather.printName(); usMother.printName(); } }
结果打印如下,功能正常: