抽象工厂模式:用于解决“多个不同类型的对象需要被同一处调用且同一类型的不同对象需要被多处调用”的情景。
示例说明:工厂A(FactoryA)可以生产电脑A(ComputerA)和手机A(MobilePhoneA),工厂B(FactoryB)也可以生产电脑B(ComputerB)和手机B(MobilePhoneB)。要求程序可以灵活的添加手机产品和电脑产品。
优势:便于添加同类型的产品,例如添加 ComputerC、ComputerD、MobilePhoneC、MobilePhoneD
劣势:不便于类型的扩展,例如添加CDPlayer产品,添加TV产品。
类图如下:
看代码:
定义电脑接口:
package com.zpj.designMode.abstractFactory; public interface Computer{ public void IamComputer(); }
添加两个实现类
ComputerA :
package com.zpj.designMode.abstractFactory; public class ComputerA implements Computer{ @Override public void IamComputer() { System.out.println("---------- i am ComputerA and from FactoryA----"); } }
ComputerB :
package com.zpj.designMode.abstractFactory; public class ComputerB implements Computer{ @Override public void IamComputer() { System.out.println("---------- i am ComputerB and from FactoryB----"); } }
定义手机接口:MobilePhone
package com.zpj.designMode.abstractFactory; public interface MobilePhone{ public void IamMobilePhone(); }
手机接口实现类:MobilePhoneA
package com.zpj.designMode.abstractFactory; public class MobilePhoneA implements MobilePhone{ @Override public void IamMobilePhone() { System.out.println("---i am MobilePhoneA and from FactoryA.-----"); } }
手机接口实现类:MobilePhoneA
package com.zpj.designMode.abstractFactory; public class MobilePhoneB implements MobilePhone{ @Override public void IamMobilePhone() { System.out.println("---i am MobilePhoneB and from FactoryB.-----"); } }
定义工厂接口:Factory
package com.zpj.designMode.abstractFactory; public interface Factory { //工厂中的都可以生产这两种产品 public Computer createCompulter(); public MobilePhone createMobilePhone(); }
工厂实现类:FactoryA
package com.zpj.designMode.abstractFactory; public class FactoryA implements Factory{ public Computer createCompulter(){ return new ComputerA(); }; public MobilePhone createMobilePhone(){ return new MobilePhoneA(); }; }
工厂实现类:FactoryB
package com.zpj.designMode.abstractFactory; public class FactoryB implements Factory{ public Computer createCompulter(){ return new ComputerB(); }; public MobilePhone createMobilePhone(){ return new MobilePhoneB(); }; }
测试类:
package com.zpj.designMode.abstractFactory; import org.junit.Test; public class AbstructTest { @Test public void test01() { //各个工厂可以生产各自的产品 Factory factoryA = new FactoryA(); Computer compA = factoryA.createCompulter(); compA.IamComputer(); MobilePhone mpA = factoryA.createMobilePhone(); mpA.IamMobilePhone(); Factory factoryB = new FactoryB(); Computer compB = factoryB.createCompulter(); compB.IamComputer(); MobilePhone mpB = factoryB.createMobilePhone(); mpB.IamMobilePhone(); } }
1、如果需要添加工厂FactoryC,则需要添加一个Factory的实现类:FactoryC和工厂C生产的产品ComputerC和MobilePhoneC即可。但是这里有个问题,如果FactoryC不生产Computer怎么办呢?这是Factory的接口就不能使用了,需要在定义一个新的接口。在客户端进行调用的时候使用新定义的接口进行对象接收。
2、如果新添加一个产品CDPlayer,则需要添加一个CDPlayer接口,然后添加CDPlayerA和CDPlayerB,同时需要对Factory进行修改,添加createCDPlayer方法,然后再修改所有的Factory实现类。这里问题就大了,怎么解决?
这就需要在前期进行接口设计的时候进行详细分类,同时明确好各个接口中所具有的方法种类,尽量减少因添加设备而变动的接口数量。没有完美的设计模式,只有适合的设计模式。
其次还有一种方法:组合简单工厂模式,也就是取消Factory的定义,客户端通过简单工厂模式获取各种产品的工厂,然后在进行生产。具体简单工厂怎么用见:设计模式—简单工厂
熟练使用各种模式进行组合还是很重要的!