工厂模式必备基础概念
产品
抽象产品
产品等级
产品簇
同一品牌的产品族,如阿迪的所有产品(鞋,运动上衣,运动裤等)

概念
为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。
模式结构:抽象工厂:抽象工厂产品:抽象产品:具体产品
抽象工厂:提供了创建产品的接口,它包含了多个创建产品的方法,可以创建多个不同等级的产品
抽象工厂产品:实现了抽象工厂的多个抽象方法,完成了具体产品的创建
抽象产品:定义了产品的规范,描述了产品的主要特征和功能
具体产品:实现了抽象产品的多个接口,由抽象工厂产品创建
推演
工厂方法例子
生产8毫米及6毫米螺丝的需求
/*** 螺丝工厂接口*/interface ScrewFactory{Screw getScrew();}/*** 工厂接口具体产品 - 8毫米螺丝工厂*/class EightScrewFactory implements ScrewFactory {@Overridepublic Screw getScrew() {return new EightScrew();}}/*** 工厂接口具体产品 - 6毫米螺丝工厂*/class SixScrewFactory implements ScrewFactory {@Overridepublic Screw getScrew() {return new SixScrew();}}/*** 接口类,抽象产品-螺丝*/interface Screw{Integer getDiameter();}/*** 实现类,具体产品-8毫米螺丝*/class EightScrew implements Screw {@Overridepublic Integer getDiameter() {return 8;}}/*** 实现类,具体产品-6毫米螺丝*/class SixScrew implements Screw {@Overridepublic Integer getDiameter() {return 6;}}
生产8毫米和6毫米螺丝帽的需求
/*** 螺丝帽工厂接口*/interface ScrewCapFactory{ScrewCap getScrewCap();}/*** 工厂接口具体产品 - 8毫米螺丝工厂*/class EightScrewCapFactory implements ScrewCapFactory {@Overridepublic ScrewCap getScrewCap() {return new EightScrewCap();}}/*** 工厂接口具体产品 - 6毫米螺丝工厂*/class SixScrewCapFactory implements ScrewCapFactory {@Overridepublic ScrewCap getScrewCap() {return new SixScrewCap();}}/*** 接口类,抽象产品-螺丝帽*/interface ScrewCap{Integer getDiameter();}/*** 实现类,具体产品-8毫米螺丝帽*/class EightScrewCap implements ScrewCap {@Overridepublic Integer getDiameter() {return 8;}}/*** 实现类,具体产品-6毫米螺丝帽*/class SixScrewCap implements ScrewCap {@Overridepublic Integer getDiameter() {return 6;}}
客户端调用工厂生产配套的螺丝及螺丝帽
ScrewFactory screwFactory = new EightScrewFactory();ScrewCapFactory screwCapFactory = new EightScrewCapFactory();Screw screw = screwFactory.getScrew();ScrewCap screwCap = screwCapFactory.getScrewCap();System.out.println("螺丝直径:"+screw.getDiameter()+"mm ----螺丝帽直径:"+screwCap.getDiameter()+"mm");
上述例子中,螺丝和螺丝帽是产品等级,Screw和ScrewCap都是抽象产品,而8毫米和6毫米螺丝(EightScrew和SixScrew)以及8毫米和6毫米螺丝帽(EightScrewCap 和SixScrewCap )都是产品
此时如果增加了一个产品等级如扳手,代码需要变动的地方分别是:
新增一个抽象产品——Spanner
新增两个具体产品——EightSpanner和SixSpanner
新增一个抽象工厂——SpannerFactory
新增两个工厂实现——EightSpannerFactory和SixSpannerFactory
此时客户端调用代码变动如下:
ScrewFactory screwFactory = new EightScrewFactory();ScrewCapFactory screwCapFactory = new EightScrewCapFactory();Screw screw = screwFactory.getScrew();ScrewCap screwCap = screwCapFactory.getScrewCap();SpannerFactory spannerFactory= new EightSpannerFactory();Spanner spanner = spannerFactory.getSpanner();System.out.println("螺丝直径:"+screw.getDiameter()+"mm ----螺丝帽直径:"+screwCap.getDiameter()+"mm ----扳手直径:"+spanner.getDiameter()+"mm");
所以,工厂方法模式的弊端出现了,每添加了一个具体产品,都需要新增一个对应的具体工厂类,增加了代码的复杂度
抽象工厂例子
上述说明中,螺丝和螺丝帽是产品等级,Screw和ScrewCap都是抽象产品,而8毫米和6毫米螺丝(EightScrew和SixScrew)以及8毫米和6毫米螺丝帽(EightScrewCap 和SixScrewCap )都是产品
那么,很明显,螺丝和螺丝帽的组合,是一个产品簇(如8毫米螺丝和8毫米螺丝帽),抽象工厂则是将这种关联依赖形成统一的工厂进行生产
整合后代码如下:**
/*** 抽象工厂,统一产品工厂*/interface UnifiedFactory{Screw getScrew();ScrewCap getScrewCap();}/*** 工厂接口具体产品 - 8毫米产品统一工厂*/class EightUnifiedFactory implements UnifiedFactory{@Overridepublic Screw getScrew() {return new EightScrew();}@Overridepublic ScrewCap getScrewCap() {return new EightScrewCap();}}/*** 工厂接口具体产品 - 6毫米产品统一工厂*/class SixUnifiedFactory implements UnifiedFactory {@Overridepublic Screw getScrew() {return new SixScrew();}@Overridepublic ScrewCap getScrewCap() {return new SixScrewCap();}}/*** 接口类,抽象产品-螺丝*/interface Screw{Integer getDiameter();}/*** 实现类,具体产品-8毫米螺丝*/class EightScrew implements Screw {@Overridepublic Integer getDiameter() {return 8;}}/*** 实现类,具体产品-6毫米螺丝*/class SixScrew implements Screw {@Overridepublic Integer getDiameter() {return 6;}}/*** 接口类,抽象产品-螺丝帽*/interface ScrewCap{Integer getDiameter();}/*** 实现类,具体产品-8毫米螺丝帽*/class EightScrewCap implements ScrewCap {@Overridepublic Integer getDiameter() {return 8;}}/*** 实现类,具体产品-6毫米螺丝帽*/class SixScrewCap implements ScrewCap {@Overridepublic Integer getDiameter() {return 6;}}
客户端调用代码如下
UnifiedFactory unifiedFactory = new EightUnifiedFactory();System.out.println("螺丝直径:"+unifiedFactory.getScrew().getDiameter()+"mm ----螺丝帽直径:"+unifiedFactory.getScrewCap().getDiameter()+"mm");
此时如果新增产品等级扳手(Spanner),则只需要如下操作:
新增一个抽象产品——Spanner
新增两个具体产品——EightSpanner和SixSpanner
在UnifiedFactory中新增方法Spanner getSpanner();
在EightUnifiedFactory和SixUnifiedFactory中实现getSpanner()方法分别生产EightSpanner和SixSpanner**
如此,便可解决工厂方法模式中的弊端,减少工厂的数量
应用场景
当产品等级比较固定时,可以考虑使用抽象工厂
当产品等级经常变化时,则不建议使用抽象工厂
**
优点
缺点
如上述例子,当产品等级变化时,都要引起所有以前工厂代码的修改(如新增一个扳手产品等级,需要修改所有工厂代码),违反了“开闭原则”。
注:抽象工厂模式中,用一个工厂生产的产品都应该只属于同一个产品簇,必然存在内在联系
如有贻误,还请评论指正**
