前言:抽象工厂模式针对一系列产品(或相关的几个类),约定了某一工厂类(或接口)来定义如何生产这一系列产品,用户可以根据需要来定义不同的工厂类来产生不同系列的产品组。
栗子
如下图图1所示
看图说话
有A、B两种商品,搭配在一起销售特别火爆,于是市场上出现了同一家店同时卖这两种商品的销售套路。KFCStore和McDonaldStore这两家店也采用了这种销售套路,并在原有A、B两种商品类别的基础上进行了创新,分别开发了热辣型的AB组合和凉爽型的AB组合。对于一些吃货顾客来说,可以根据自己口味到KFCStore中购买热辣口味的AB组合,也可以去McDonaldStore中购买清爽口味的AB组合。
程序语言
商品类
public class AbstractProductA {
private String taste;
public AbstractProductA(String taste) {
this.taste = taste;
}
public String getTaste() {
return taste;
}
}
public class AbstractProductB {
private String taste;
public AbstractProductB(String taste) {
this.taste = taste;
}
public String getTaste() {
return taste;
}
}
工厂接口类
public interface AbstractStore {
AbstractProductA productAbstractProductA();
AbstractProductB productAbstractProductB();
}
实际工厂类及其产品
KFC工厂
public class KFCStore implements AbstractStore {
@Override
public AbstractProductA productAbstractProductA() {
return new HotProductA();
}
@Override
public AbstractProductB productAbstractProductB() {
return new HotProductB();
}
}
public class HotProductA extends AbstractProductA {
public HotProductA() {
super("热辣型ProductA");
}
}
public class HotProductB extends AbstractProductB {
public HotProductB() {
super("热辣型ProductB");
}
}
McDonald工厂
public class McDonaldStore implements AbstractStore {
@Override
public AbstractProductA productAbstractProductA() {
return new CoolProductA();
}
@Override
public AbstractProductB productAbstractProductB() {
return new CoolProductB();
}
}
public class CoolProductA extends AbstractProductA {
public CoolProductA() {
super("凉爽型ProductA");
}
}
public class CoolProductB extends AbstractProductB {
public CoolProductB() {
super("凉爽型ProductB");
}
}
客户类
public class Customer {
public void walkIntoStoreAndEatAB(AbstractStore store) {
System.out.println("今天吃了这么多:");
AbstractProductA productA = store.productAbstractProductA();
AbstractProductB productB = store.productAbstractProductB();
eatA(productA);
eatB(productB);
}
public void eatA(AbstractProductA productA) {
System.out.println(productA.getTaste());
}
public void eatB(AbstractProductB productB) {
System.out.println(productB.getTaste());
}
}
场景入口
public class Main {
public static void main(String[] args) {
Customer customer = new Customer();
AbstractStore kfc = new KFCStore();
AbstractStore mcDonaldStore = new McDonaldStore();
System.out.println("************第一天************");
//第一天碰到了kfc店
customer.walkIntoStoreAndEatAB(kfc);
System.out.println("************第二天************");
//第二天刚好碰到了mcDonald店
customer.walkIntoStoreAndEatAB(mcDonaldStore);
}
}
场景说明
通过程序对抽象工厂的一般模式(如图1)进行了实现,实际使用中,客户端程序可以根据实际需要实例化不同的工厂类,并使用工厂类生产的一系列产品。
抽象工厂模式效果
1、通过抽象工厂类或接口,将不同的产品捆绑成一个系列,并通过子工厂类来实例化同一系列中的不同产品,将不同的产品捆绑成了一个系列;
2、Client使用时,某一时刻只能使用工厂提供的同一系列的产品,但是可以方便的更换整个产品的系列;
3、难以增加新产品,如图1所示,当计划将AbstractProductC加入到该销售套路中来时,同时需要修改抽象工厂类及其子类,违反了开闭原则。