抽象工厂模式是什么
之前一文中,有提到工厂模式,工厂模式是能创建一种类型产品的工厂,而抽象工厂则是一个超级工厂,它定义了多种类型产品的工厂。即抽象工厂定义了一个超级工厂,用户创建相关或者有依赖关系的对象簇,而无序制定具体的类。讲工厂抽象成2层,由抽象工厂(超级工厂)和具体实现的工厂子类(产品簇工厂)组成。程序员可以根据创建对应的对象类型来使用对应的工厂子类。这样将单个简单的工厂诶变成工厂簇,更加利于代码的维护和扩展
抽象工厂优缺点
优点:当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。
缺点:产品族扩展非常困难,要增加一个系列的某一产品,既要在抽象的 Creator 里加代码,又要在具体的里面加代码。
抽象工厂示例代码
关系图示
抽象产品:它是定义产品的接口,是工厂方法模式所创建对象的超类型,也就是产品对象的公共父类。
具体产品:它实现了抽象产品接口,某种类型的具体产品由专门的具体工厂创建,具体工厂和具体产品之间一一对应。
抽象工厂: 定义一个工厂方法用来返回一个产品,抽象工厂是工厂方法模式的核心,所有创建对象的工厂类都必须实现该接口。
具体工厂:实现了抽象工厂制造对象的方法,由调用着决定需要制作的对象,返回一个具体的实例对象。
模拟代码
酸奶和牛奶是两种不同的制品,通过两种工厂提供给客户,客户通过工厂获取器获取到指定的工厂并得到对应的制品。工厂内部的逻辑调用者无需关注。只需要关注自己获取到东西以及如何去获取。
1、抽象工厂
public interface AbstractFactory { Milk getMilk(String milkType); Yogurt getyogurt(String yogurtType); }
2、具体工厂:牛奶工厂
public class MilkFactory implements AbstractFactory{ public Milk getMilk(String milkType){ Milk milk = null; if(milkType == null){ return null; } if(milkType.equalsIgnoreCase("TeLunSu")){ milk = new MilkTeLunSu(); } else if(milkType.equalsIgnoreCase("MengNiu")){ milk = new MilkMengNiu(); } else if(milkType.equalsIgnoreCase("YiLi")){ milk = new MilkYiLi(); } milk.prepareRawMaterials(); milk.obtainRawMaterials(); milk.machiningObtainRawMaterials(); milk.productionCompleted(); milk.doPackage(); return milk; } @Override public Yogurt getyogurt(String yogurtType) { return null; } }
3、具体工厂:酸奶工厂
public class YogurtFactory implements AbstractFactory{ public Yogurt getyogurt(String milkType){ Yogurt yogurt = null; if(milkType == null){ return null; } if(milkType.equalsIgnoreCase("AnMuxi")){ yogurt = new YogurtAnMuXi(); } else if(milkType.equalsIgnoreCase("MengNiu")){ yogurt = new YogurtMengNiu(); } else if(milkType.equalsIgnoreCase("YiLi")){ yogurt = new YogurtYiLi(); } yogurt.prepareRawMaterials(); yogurt.obtainRawMaterials(); yogurt.machiningObtainRawMaterials(); yogurt.productionCompleted(); yogurt.doPackage(); return yogurt; } @Override public Milk getMilk(String yogurtType) { return null; } }
4、抽象产品:牛奶
public abstract class Milk { public abstract void getSelfInfo(); public abstract void prepareRawMaterials(); void obtainRawMaterials() { System.out.println("获取对应原材料"); } void machiningObtainRawMaterials(){ System.out.println("加工原材料"); } void productionCompleted(){ System.out.println("牛奶生产完成"); } void doPackage(){ System.out.println("包装成品牛奶"); } }
5、抽象产品:酸奶
public abstract class Yogurt { public abstract void getSelfInfo(); public abstract void prepareRawMaterials(); void obtainRawMaterials() { System.out.println("获取对应原材料"); } void machiningObtainRawMaterials(){ System.out.println("加工原材料"); } void productionCompleted(){ System.out.println("酸奶生产完成"); } void doPackage(){ System.out.println("包装成品酸奶"); } }
6、抽象产品牛奶的三个具体实现类
public class MilkMengNiu extends Milk{ @Override public void getSelfInfo() { System.out.println("我是蒙牛牛奶"); } @Override public void prepareRawMaterials() { System.out.println("采购制作蒙牛牛奶的原材料"); } }
public class MilkTeLunSu extends Milk { @Override public void getSelfInfo() { System.out.println("我是特仑苏牛奶"); } @Override public void prepareRawMaterials() { System.out.println("采购制作特仑苏牛奶的原材料"); } }
public class MilkYiLi extends Milk { @Override public void getSelfInfo() { System.out.println("我是伊利牛奶"); } @Override public void prepareRawMaterials() { System.out.println("采购制作伊利牛奶的原材料"); } }
7、抽象产品酸奶的三个具体实现类
public class YogurtAnMuXi extends Yogurt{ @Override public void getSelfInfo() { System.out.println("我是安慕希酸奶"); } @Override public void prepareRawMaterials() { System.out.println("采购制作安慕希酸奶的原材料"); } }
public class YogurtMengNiu extends Yogurt{ @Override public void getSelfInfo() { System.out.println("我是蒙牛酸奶"); } @Override public void prepareRawMaterials() { System.out.println("采购制作蒙牛酸奶的原材料"); } }
public class YogurtYiLi extends Yogurt{ @Override public void getSelfInfo() { System.out.println("我是伊利酸奶"); } @Override public void prepareRawMaterials() { System.out.println("采购制作伊利酸奶的原材料"); } }
8、工厂生产者(创建指定工厂供调用着使用)
/** * 工厂生产者,给予调用着client所要创建的具体工厂 */ public class FactoryProducer { public static AbstractFactory getFactory(String choiceFactoryParam){ if (choiceFactoryParam.equals("MILK")) return new MilkFactory(); if (choiceFactoryParam.equals("YOGURT")) return new YogurtFactory(); return null; } }
9、客户端(使用工厂)
public class TestClient { public static void main(String[] args) { AbstractFactory milkFactory = FactoryProducer.getFactory("MILK"); AbstractFactory yogurtFactory = FactoryProducer.getFactory("YOGURT"); Milk mengNiuMilk = milkFactory.getMilk("MengNiu"); mengNiuMilk.getSelfInfo(); System.out.println("-------------------------------"); Milk teLunSuMilk = milkFactory.getMilk("TeLunSu"); teLunSuMilk.getSelfInfo(); System.out.println("-------------------------------"); Milk yiLiMilk = milkFactory.getMilk("YiLi"); yiLiMilk.getSelfInfo(); System.out.println("-------------------------------"); Yogurt anMuXiYogurt = yogurtFactory.getyogurt("AnMuXi"); anMuXiYogurt.getSelfInfo(); System.out.println("-------------------------------"); Yogurt mengNiuYogurt = yogurtFactory.getyogurt("MengNiu"); mengNiuYogurt.getSelfInfo(); System.out.println("-------------------------------"); Yogurt yiLiYogurt = yogurtFactory.getyogurt("YiLi"); yiLiYogurt.getSelfInfo(); } }
调用结果
采购制作蒙牛牛奶的原材料 获取对应原材料 加工原材料 牛奶生产完成 包装成品牛奶 我是蒙牛牛奶 ------------------------------- 采购制作特仑苏牛奶的原材料 获取对应原材料 加工原材料 牛奶生产完成 包装成品牛奶 我是特仑苏牛奶 ------------------------------- 采购制作伊利牛奶的原材料 获取对应原材料 加工原材料 牛奶生产完成 包装成品牛奶 我是伊利牛奶 ------------------------------- 采购制作安慕希酸奶的原材料 获取对应原材料 加工原材料 酸奶生产完成 包装成品酸奶 我是安慕希酸奶 ------------------------------- 采购制作蒙牛酸奶的原材料 获取对应原材料 加工原材料 酸奶生产完成 包装成品酸奶 我是蒙牛酸奶 ------------------------------- 采购制作伊利酸奶的原材料 获取对应原材料 加工原材料 酸奶生产完成 包装成品酸奶 我是伊利酸奶