1. 简介
抽象工厂模式其实就是在简单工厂模式上面,由原来单一的工厂,变成多个工厂的,即增添一个抽象工厂类;
1.2 解决的问题是:
- 简单工厂的缺点,当工厂挂了,没办法进行,抽象工厂解决了这个问题;
- 简答工厂模式生产一类产品,抽象工厂生产多个产品
1.3 模式组成
组成(角色) | 关系 | 作用 |
---|---|---|
抽象产品族(AbstractProduct) | 抽象产品的父类 | 描述抽象产品的公共接口 |
抽象产品 | (Product 具体产品的父类 | 描述具体产品的公共接口 |
具体产品 | (Concrete Product) 抽象产品的子类; | 工厂类创建的目标类 |
抽象工厂(Creator) | 具体工厂的父类 | 描述具体工厂的公共接口 |
具体工厂(Concrete Creator) | 抽象工厂的子类; | 被外界调用 描述具体工厂;实现FactoryMethod工厂方法创建产品的实例 |
1.4 使用步骤
创建抽象工厂类,定义具体工厂的公共接口;
创建抽象产品族类 ,定义抽象产品的公共接口;
创建抽象产品类 (继承抽象产品族类),定义具体产品的公共接口;
创建具体产品类(继承抽象产品类) & 定义生产的具体产品;
创建具体工厂类(继承抽象工厂类),定义创建对应具体产品实例的方法;
客户端通过实例化具体的工厂类,并调用其创建不同目标产品的方法创建不同具体产品类的实例
2. 代码演示
2.1 抽象工厂
package abstractfactory;
import abstractfactory.abstractProduct.productImpl.AbstractProduct;
/**
* 抽象工厂
*/
public abstract class Factory {
//容器
public abstract AbstractProduct ManufactureContainer();
//模具
public abstract AbstractProduct ManufactureMould();
}
2.2 抽象工厂的子类,具体工厂A
package abstractfactory.abstractProduct.factoryImpl;
import abstractfactory.Factory;
import abstractfactory.abstractProduct.productImpl.AbstractProduct;
import abstractfactory.abstractProduct.productImpl.ContainerProductA;
import abstractfactory.abstractProduct.productImpl.MouldProductA;
//A厂 - 生产模具+容器产品
public class FactoryA extends Factory {
@Override
public AbstractProduct ManufactureContainer() {
return new ContainerProductA();
}
@Override
public AbstractProduct ManufactureMould() {
return new MouldProductA();
}
}
2.3 抽象工厂的子类,具体工厂B
package abstractfactory.abstractProduct.factoryImpl;
import abstractfactory.Factory;
import abstractfactory.abstractProduct.productImpl.AbstractProduct;
import abstractfactory.abstractProduct.productImpl.ContainerProductB;
import abstractfactory.abstractProduct.productImpl.MouldProductB;
//B厂 - 生产模具+容器产品
public class FactoryB extends Factory {
@Override
public AbstractProduct ManufactureContainer() {
return new ContainerProductB();
}
@Override
public AbstractProduct ManufactureMould() {
return new MouldProductB();
}
}
2.4 抽象产品父类
package abstractfactory.abstractProduct.productImpl;
/**
* 创建抽象产品族类 ,定义具体产品的公共接口;
*/
public abstract class AbstractProduct{
public abstract void method1();
}
2.5 抽象产品父类的子抽象类–容器产品抽象类
package abstractfactory.abstractProduct.productImpl;
//容器产品抽象类
public abstract class ContainerProduct extends AbstractProduct {
@Override
public abstract void method1();
}
2.5.1容器产品抽象类–实现类-容器产品A类
package abstractfactory.abstractProduct.productImpl;
//容器产品A类
public class ContainerProductA extends ContainerProduct {
@Override
public void method1() {
System.out.println("生产出了容器产品A");
}
}
2.5.2 容器产品抽象类–实现类-容器产品B类
package abstractfactory.abstractProduct.productImpl;
//容器产品B类
public class ContainerProductB extends ContainerProduct {
@Override
public void method1() {
System.out.println("生产出了容器产品B");
}
}
2.6 抽象产品父类的子抽象类–模具产品抽象类
package abstractfactory.abstractProduct.productImpl;
//模具产品抽象类
public abstract class MouldProduct extends AbstractProduct {
@Override
public abstract void method1();
}
2.6.1 模具产品抽象类–实现类-模具产品A类
package abstractfactory.abstractProduct.productImpl;
//模具产品A类
public class MouldProductA extends MouldProduct {
@Override
public void method1() {
System.out.println("生产出了模具产品A");
}
}
2.6.2 模具产品抽象类–实现类-模具产品B类
package abstractfactory.abstractProduct.productImpl;
//模具产品B类
public class MouldProductB extends MouldProduct {
@Override
public void method1() {
System.out.println("生产出了模具产品B");
}
}
3.测试类
package abstractfactory;
import abstractfactory.abstractProduct.factoryImpl.FactoryA;
import abstractfactory.abstractProduct.factoryImpl.FactoryB;
public class AbstractFactoryPattern {
public static void main(String[] args){
FactoryA mFactoryA = new FactoryA();
FactoryB mFactoryB = new FactoryB();
//A厂当地客户需要容器产品A
mFactoryA.ManufactureContainer().method1();
//A厂当地客户需要模具产品A
mFactoryA.ManufactureMould().method1();
//B厂当地客户需要容器产品B
mFactoryB.ManufactureContainer().method1();
//B厂当地客户需要模具产品B
mFactoryB.ManufactureMould().method1();
}
}
4. 小总结
4.1 优点
可以在类的内部对产品族中相关联的多等级产品共同管理,而不必专门引入多个新的类来进行管理。
当需要产品族时,抽象工厂可以保证客户端始终只使用同一个产品的产品组。
抽象工厂增强了程序的可扩展性,当增加一个新的产品族时,不需要修改原代码,满足开闭原则。
4.2 缺点
当产品族中需要增加一个新的产品时,所有的工厂类都需要进行修改。增加了系统的抽象性和理解难度。
这是因为抽象工厂接口中已经确定了可以被创建的产品集合,如果需要添加新产品,此时就必须去修改抽象工厂的接口,这样就涉及到抽象工厂类的以及所有子类的改变,这样也就违背了“开发——封闭”原则。
对于新的产品族符合开-闭原则;对于新的产品种类不符合开-闭原则,这一特性称为开-闭原则的倾斜性。
应用场景
程序需要处理不同系列的相关产品,但是您不希望它依赖于这些产品的具体类时,可以使用抽象工厂。