抽象工厂模式相对于工厂方法模式来说,就是工厂方法模式是针对一个产品系列的,而抽象工厂模式是针对多个产品系列的,即工厂方法模式是一个产品系列一个工厂类,而抽象工厂模式是多个产品系列一个工厂类。
抽象工厂模式特点:抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的一种形态。抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体的情况下,创建多个产品族中的产品对象。它有多个抽象产品类,每个抽象产品类可以派生出多个具体产品类,一个抽象工厂类,可以派生出多个具体工厂类,每个具体工厂类可以创建多个具体产品类的实例。每一个模式都是针对一定问题的解决方案,工厂方法模式针对的是一个产品等级结构;而抽象工厂模式针对的是多个产品等级结果。
抽象工厂中包含4个角色:
- 抽象工厂角色
- 具体工厂角色
- 抽象产品角色
- 具体产品角色
抽象工厂模式的类图如下:
抽象工厂模式代码如下:
第一部分:武器产品族
packagecom.powernode.product;/** * 武器产品族 * @author 动力节点 * @version 1.0 * @className Weapon * @since 1.0 **/publicabstractclassWeapon{publicabstractvoidattack();}packagecom.powernode.product;/** * 武器产品族中的产品等级1 * @author 动力节点 * @version 1.0 * @className Gun * @since 1.0 **/publicclassGunextendsWeapon{@Overridepublicvoidattack(){System.out.println("开枪射击!");}}packagecom.powernode.product;/** * 武器产品族中的产品等级2 * @author 动力节点 * @version 1.0 * @className Dagger * @since 1.0 **/publicclassDaggerextendsWeapon{@Overridepublicvoidattack(){System.out.println("砍丫的!");}}第二部分:水果产品族
packagecom.powernode.product;/** * 水果产品族 * @author 动力节点 * @version 1.0 * @className Fruit * @since 1.0 **/publicabstractclassFruit{/** * 所有果实都有一个成熟周期。 */publicabstractvoidripeCycle();}packagecom.powernode.product;/** * 水果产品族中的产品等级1 * @author 动力节点 * @version 1.0 * @className Orange * @since 1.0 **/publicclassOrangeextendsFruit{@OverridepublicvoidripeCycle(){System.out.println("橘子的成熟周期是10个月");}}packagecom.powernode.product;/** * 水果产品族中的产品等级2 * @author 动力节点 * @version 1.0 * @className Apple * @since 1.0 **/publicclassAppleextendsFruit{@OverridepublicvoidripeCycle(){System.out.println("苹果的成熟周期是8个月");}}第三部分:抽象工厂类
packagecom.powernode.factory;importcom.powernode.product.Fruit;importcom.powernode.product.Weapon;/** * 抽象工厂 * @author 动力节点 * @version 1.0 * @className AbstractFactory * @since 1.0 **/publicabstractclassAbstractFactory{publicabstractWeapongetWeapon(Stringtype);publicabstractFruitgetFruit(Stringtype);}第四部分:具体工厂类
packagecom.powernode.factory;importcom.powernode.product.Dagger;importcom.powernode.product.Fruit;importcom.powernode.product.Gun;importcom.powernode.product.Weapon;/** * 武器族工厂 * @author 动力节点 * @version 1.0 * @className WeaponFactory * @since 1.0 **/publicclassWeaponFactoryextendsAbstractFactory{publicWeapongetWeapon(Stringtype){if(type==null||type.trim().length()==0){returnnull;}if("Gun".equals(type)){returnnewGun();}elseif("Dagger".equals(type)){returnnewDagger();}else{thrownewRuntimeException("无法生产该武器");}}@OverridepublicFruitgetFruit(Stringtype){returnnull;}}packagecom.powernode.factory;importcom.powernode.product.*;/** * 水果族工厂 * @author 动力节点 * @version 1.0 * @className FruitFactory * @since 1.0 **/publicclassFruitFactoryextendsAbstractFactory{@OverridepublicWeapongetWeapon(Stringtype){returnnull;}publicFruitgetFruit(Stringtype){if(type==null||type.trim().length()==0){returnnull;}if("Orange".equals(type)){returnnewOrange();}elseif("Apple".equals(type)){returnnewApple();}else{thrownewRuntimeException("我家果园不产这种水果");}}}第五部分:客户端程序
packagecom.powernode.client;importcom.powernode.factory.AbstractFactory;importcom.powernode.factory.FruitFactory;importcom.powernode.factory.WeaponFactory;importcom.powernode.product.Fruit;importcom.powernode.product.Weapon;/** * @author 动力节点 * @version 1.0 * @className Client * @since 1.0 **/publicclassClient{publicstaticvoidmain(String[]args){// 客户端调用方法时只面向AbstractFactory调用方法。AbstractFactoryfactory=newWeaponFactory();// 注意:这里的new WeaponFactory()可以采用 简单工厂模式 进行隐藏。Weapongun=factory.getWeapon("Gun");Weapondagger=factory.getWeapon("Dagger");gun.attack();dagger.attack();AbstractFactoryfactory1=newFruitFactory();// 注意:这里的new FruitFactory()可以采用 简单工厂模式 进行隐藏。Fruitorange=factory1.getFruit("Orange");Fruitapple=factory1.getFruit("Apple");orange.ripeCycle();apple.ripeCycle();}}抽象工厂模式的优缺点:
- 优点:当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。
- 缺点:产品族扩展非常困难,要增加一个系列的某一产品,既要在AbstractFactory里加代码,又要在具体的里面加代码。