设计模式-抽象工厂
抽象工厂模式:
最复杂的 工厂模式的变种
抽象工厂模式,叫做abstract factory模式,它其实也是简单工厂模式的一个变种,但是 它是最复杂的一个变种。
场景介绍:
它针对的是这昂zi的一个场景:
(1) 我们现在要生产的,不是一个一个的这个产品,而是一个一个的产品组合;
(2) 比如说,我们有产品A、B、C 三种,现在 第一种产品组合是 A+B,第二种产品组合是 B+C,第三种产品组合是 A+C;
(3) 这个,其实就是 要对工厂模式 进行进一步的增强。
不用抽象工厂模式的实现:
那么,不用模式,我们来做的话,应该怎么来做的,先创建一个类,叫做WithoutAbstractFactoryPatternDemo。
然后,简单工厂模式,模板方法模式,工厂方法模式,以及 抽象工厂模式,其实,我们可以把 工厂相关的这个模式,给它放一块去记忆和总结,因为它们是相互关联的,ok。
public class WithoutAbstractFactoryPatternDemo { public interface Product { void execute(); } public static class Product1 implements Product { @Override public void execute() { System.out.println("产品1的功能逻辑"); } } public static class Product2 implements Product { @Override public void execute() { System.out.println("产品2的功能逻辑"); } } public static class Product3 implements Product { @Override public void execute() { System.out.println("产品3的功能逻辑"); } } }
接下来,再写一个main方法,在面方法里面应该是这样的。比如说,我们有这样的一些产品,假设我们现在要创建这个产品,是 产品1+产品2 的一个组合。
如果用简单工厂模式来实现,我们来看看 会有什么样的问题,这里我们给它每个产品类,先来搞一个工厂:
public static class Product1Factory { public static Product createProduct() { return new Product1(); } } public static class Product2Factory { public static Product createProduct() { return new Product2(); } } public static class Product3Factory { public static Product createProduct() { return new Product3(); } }
也就是 每个产品,它都有一个自己的工厂。这时候,要创建这个 产品1+产品2 的一个组合,实现如下:
public static void main(String[] args) { // 我们现在要创建产品1+产品2的组合 Product product1 = Product1Factory.createProduct(); Product product2 = Product2Factory.createProduct(); product1.execute(); product2.execute(); }
执行输出一下:
产品1的功能逻辑
产品2的功能逻辑
我们要创建这么一种组合,这是产品1和2的功能逻辑。这个是一种。
现在比如说,我们 要创建那个 产品2 + 产品3 的一个组合,然后 把产品1+产品2的组合,给它注掉,这边是 创建 产品2+产品3,代码实现:
// 我们现在要创建产品2+产品3的组合 Product product2 = Product2Factory.createProduct(); Product product3 = Product3Factory.createProduct(); product2.execute(); product3.execute();
然后又是,要创建 产品1 + 产品3 的这么一个组合,把产品2+产品3的组合注掉,同样,这边是 产品1+产品3,
不用抽象工厂模式的完整代码实现1如下:
public class WithoutAbstractFactoryPatternDemo { public static void main(String[] args) { // 我们现在要创建产品1+产品2的组合 // Product product1 = Product1Factory.createProduct(); // Product product2 = Product2Factory.createProduct(); // // product1.execute(); // product2.execute(); // // 我们现在要创建产品2+产品3的组合 // Product product2 = Product2Factory.createProduct(); // Product product3 = Product3Factory.createProduct(); // // product2.execute(); // product3.execute(); // 我们现在要创建产品1+产品3的组合 Product product1 = Product1Factory.createProduct(); Product product3 = Product3Factory.createProduct(); product1.execute(); product3.execute(); } public interface Product { void execute(); } public static class Product1 implements Product { @Override public void execute() { System.out.println("产品1的功能逻辑"); } } public static class Product2 implements Product { @Override public void execute() { System.out.println("产品2的功能逻辑"); } } public static class Product3 implements Product { @Override public void execute() { System.out.println("产品3的功能逻辑"); } } public static class Product1Factory { public static Product createProduct() { return new Product1(); } } public static class Product2Factory { public static Product createProduct() { return new Product2(); } } public static class Product3Factory { public static Product createProduct() { return new Product3(); } } }
通过以上3种产品的组合示例,也就是说,它是什么意思呢,它其实是要,创建一组一组的这个产品。
为了方便去形容,它要创建一组一组的这个产品,我其实应该把它再变一下。先把每一种产品的工厂去掉,然后,我们应该有一个ProductA的接口,这么一个东西。
接下来,我们现在有 ProductA1,然后,ProductA2,然后,ProductA3,这样子。代码如下:
public interface ProductA { void execute(); } public static class ProductA1 implements ProductA { public void execute() { System.out.println("产品A1的功能逻辑"); } } public static class ProductA2 implements ProductA { public void execute() { System.out.println("产品A2的功能逻辑"); } } public static class ProductA3 implements ProductA { public void execute() { System.out.println("产品A3的功能逻辑"); } }
然后,我们又有一套产品,叫做ProductB,ProductB1,ProductB2,然后ProductB3。
public interface ProductB { void execute(); } public static class ProductB1 implements ProductB { public void execute() { System.out.println("产品B1的功能逻辑"); } } public static class ProductB2 implements ProductB { public void execute() { System.out.println("产品B2的功能逻辑"); } } public static class ProductB3 implements ProductB { public void execute() { System.out.println("产品B3的功能逻辑"); } }
然后,在main方法里,我们现在首先是要创建,产品A1 + 产品B1 的一个组合,我们要创建产品 ProductA1 和 ProductB1,就直接新建new吧,不用工厂去模拟了。
new ProductA1 和 new ProductB1,也就是A1+B1,这现在是一个组合。
然后又是创建,产品A2 和 产品B2 的这么一个组合,new ProductA2 和 这个 new ProductB2。来拷贝3组,然后是创建 产品A3 + 产品B3,new ProductA3 + new ProductB3,ok,我们现在就做出来了 ,这样的一个例子。代码实现:
public static void main(String[] args) { // 我们现在要创建产品A1+产品B1的组合 ProductA productA1 = new ProductA1(); ProductB productB1 = new ProductB1(); productA1.execute(); productB1.execute(); // 要创建产品A2+产品B2的组合 ProductA productA2 = new ProductA2(); ProductB productB2 = new ProductB2(); productA2.execute(); productB2.execute(); // 要创建产品A3+产品B3的组合 ProductA productA3 = new ProductA3(); ProductB productB3 = new ProductB3(); productA3.execute(); productB3.execute(); }
执行输出一下结构,可以看一下是,
产品A1的功能逻辑
产品B1的功能逻辑
产品A2的功能逻辑
产品B2的功能逻辑
产品A3的功能逻辑
产品B3的功能逻辑
就是说产品A1+B1,它是一个组合,产品A2+B2,是一个组合,然后 产品A3+B3,是一个组合。
那么现在的话呢,就是有一个问题。 我现在要把产品 A1+B1 的这个组合,变成 产品A1 + 产品B3,那怎么办,改代码呗,修改代码。
你这边 本来是A1+B1,就得改成A1+B3,然后这个就是一个组合。我这边 还得给它重新起一个名字 otherProductB3。
WithoutAbstractFactoryPatternDemo的完整代码2如下:
public class WithoutAbstractFactoryPatternDemo { public static void main(String[] args) { // 我们现在要创建产品A1+产品B1的组合 // ProductA productA1 = new ProductA1(); // ProductB productB1 = new ProductB1(); // // productA1.execute(); // productB1.execute(); // 我们现在要创建产品A1+产品B3的组合 ProductA productA1 = new ProductA1(); ProductB otherProductB3 = new ProductB3(); productA1.execute(); otherProductB3.execute(); // 问题来了,调整产品组合的这个行为,如果你手动创建产品组合的代码,有100个地方,A1+B1 // 一旦要调整,就是要对100个地方的代码,手动一点一点的去修改,组合的逻辑 // 不可维护,不可扩展 // 要创建产品A2+产品B2的组合 ProductA productA2 = new ProductA2(); ProductB productB2 = new ProductB2(); productA2.execute(); productB2.execute(); // 要创建产品A3+产品B3的组合 ProductA productA3 = new ProductA3(); ProductB productB3 = new ProductB3(); productA3.execute(); productB3.execute(); } public interface ProductA { void execute(); } public static class ProductA1 implements ProductA { public void execute() { System.out.println("产品A1的功能逻辑"); } } public static class ProductA2 implements ProductA { public void execute() { System.out.println("产品A2的功能逻辑"); } } public static class ProductA3 implements ProductA { public void execute() { System.out.println("产品A3的功能逻辑"); } } public interface ProductB { void execute(); } public static class ProductB1 implements ProductB { public void execute() { System.out.println("产品B1的功能逻辑"); } } public static class ProductB2 implements ProductB { public void execute() { System.out.println("产品B2的功能逻辑"); } } public static class ProductB3 implements ProductB { public void execute() { System.out.println("产品B3的功能逻辑"); } } }
就是重新给它调整了,ok。执行输入如下:
产品A1的功能逻辑
产品B3的功能逻辑
产品A2的功能逻辑
产品B2的功能逻辑
产品A3的功能逻辑
产品B3的功能逻辑
那 所以说调整,所以说问题来了,调整产品组合的这个行为,如果说,你那个手动 创建产品组合的代码,有100个地方。比如说有100个地方,都是A1+B1这么一个组合 去创建,那一旦要那个调整,就是要对100个地方的代码,手动 一点一点的 去修改,这个 它们组合的 这个逻辑。那不可维护,不可扩展。所以说针对这个问题,才有了叫做 抽象工厂的 这么一个模式。
抽象工厂模式的实现:
我们再创建一个类,叫做AbstractFactoryPatternDemo,这块的话,我们就把它WithoutAbstractFactoryPatternDemo中的 ProductA 和 ProductB 拷贝过来,还是建这样的一套东西出来,但是我们现在要定义多个抽象工厂。
第一个是,我们叫做public interface Factory,然后,它定义了几个接口,一个是createProductA,然后是,createProductB,因为任何一个抽象工厂的实现,都是创建 某一个A 加 某一个B 的一个组合,所以说,在接口里面,定义好它们俩就可以了。
然后,public static class Factory1 implements Factory,就是第一种组合。重写createProductA,它默认的返回是ProductA1,同样,重写createProductB,它默认的返回时ProductB1,然后这个Factory1工厂,默认的组合就是 productA1 + productB1。然后是 Factory2,它第二种组合,就是 A2 + B2。第3中组合,就是 A3 + B3。代码如下:
public class AbstractFactoryPatternDemo { public interface ProductA { void execute(); } public static class ProductA1 implements ProductA { public void execute() { System.out.println("产品A1的功能逻辑"); } } public static class ProductA2 implements ProductA { public void execute() { System.out.println("产品A2的功能逻辑"); } } public static class ProductA3 implements ProductA { public void execute() { System.out.println("产品A3的功能逻辑"); } } public interface ProductB { void execute(); } public static class ProductB1 implements ProductB { public void execute() { System.out.println("产品B1的功能逻辑"); } } public static class ProductB2 implements ProductB { public void execute() { System.out.println("产品B2的功能逻辑"); } } public static class ProductB3 implements ProductB { public void execute() { System.out.println("产品B3的功能逻辑"); } } public interface Factory { ProductA createProductA(); ProductB createProductB(); } public static class Factory1 implements Factory { public ProductA createProductA() { return new ProductA1(); } public ProductB createProductB() { return new ProductB1(); } } public static class Factory2 implements Factory { public ProductA createProductA() { return new ProductA2(); } public ProductB createProductB() { return new ProductB2(); } } public static class Factory3 implements Factory { public ProductA createProductA() { return new ProductA3(); } public ProductB createProductB() { return new ProductB3(); } } }
也就是说,我们把这种组合,多个产品 组合在一起的 这个逻辑,给放到了 一个一个的 这个工厂里去,但是每个工厂都实现了 一个抽象工厂的 这么一个接口Factory。
然后,我们写一个main方法,创建第一个组合,第一个组合是那个 产品A1 + 产品B1。这时,要从工厂Factory1获取第一种组合,那么 Factory1,它还得 把自己搞成 那个单例。private static final Factory1 instance = new Factory1();,然后,加一个Factory1的私有的无参构造器(定义成单例,必须加上,默认的构造器是public的),private Factory1() {},最后,public static Factory1 get() { return instance;},通过公有的get方法返回Factory1实例,然后Factory2和Factory3,每一个工厂给它做成一个单例。以Factory1示例代码实现:
public static class Factory1 implements Factory { private static final Factory1 instance = new Factory1(); private Factory1() {} public static Factory1 get() { return instance; } public ProductA createProductA() { return new ProductA1(); } public ProductB createProductB() { return new ProductB1(); } }
然后,在main方法这边就是,ProductA productA = Factory1.get().createProductA();,ProductB productB = Factory1.get().createProductB,通过这个Factory1工厂,拿到了一套组合。然后,我们可以叫做firstProductA,就是第1种组合,
// 产品A1+产品B1 ProductA firstProductA = Factory1.get().createProductA(); ProductB firstProductB = Factory1.get().createProductB();
然后,第二种是产品A2+B2,就是把第一种组合的firstProduct,这个给它改成secondProduct,然后,它是通过工厂2,去拿到的一组组合对。同样,产品A3+产品B3,这是third,然后是分别执行它们。
public static void main(String[] args) { // 产品A1+产品B1 ProductA firstProductA = Factory1.get().createProductA(); ProductB firstProductB = Factory1.get().createProductB(); firstProductA.execute(); firstProductB.execute(); // 产品A2+产品B2 ProductA secondProductA = Factory2.get().createProductA(); ProductB secondProductB = Factory2.get().createProductB(); secondProductA.execute(); secondProductB.execute(); // 产品A3+产品B3 ProductA thirdProductA = Factory3.get().createProductA(); ProductB thirdProductB = Factory3.get().createProductB(); thirdProductA.execute(); thirdProductB.execute(); }
然后,这一套产品组合就出来了,执行结果如下:
产品A1的功能逻辑
产品B1的功能逻辑
产品A2的功能逻辑
产品B2的功能逻辑
产品A3的功能逻辑
产品B3的功能逻辑
输出了A1B1,A2B2,A3B3,就是我们通过一个工厂,这个工厂里面,它就是定死了说,每个 A+B 的组合 分别是什么,如果说现在要把 A1+B1,把这个产品 改成A1+B3,这个时候,只要找到Factory1,把Factory1中的 这个B1,给它改成B3就可以了,
public static class Factory1 implements Factory { private static final Factory1 instance = new Factory1(); private Factory1() {} public static Factory1 get() { return instance; } public ProductA createProductA() { return new ProductA1(); } public ProductB createProductB() { //return new ProductB1(); return new ProductB3(); } }
这个一改就相当于是,Factory1这个组合就改了,而main中调用的方法连动都不用动,执行这跑,结果如下:
产品A1的功能逻辑
产品B3的功能逻辑
产品A2的功能逻辑
产品B2的功能逻辑
产品A3的功能逻辑
产品B3的功能逻辑
输出了A1B3组合,A2B2组合,A3B3组合。
抽象工厂模式的完整代码实现:
public class AbstractFactoryPatternDemo { public static void main(String[] args) { // 产品A1+产品B1 -> 产品A1+产品B3 ProductA firstProductA = Factory1.get().createProductA(); ProductB firstProductB = Factory1.get().createProductB(); firstProductA.execute(); firstProductB.execute(); // 产品A2+产品B2 ProductA secondProductA = Factory2.get().createProductA(); ProductB secondProductB = Factory2.get().createProductB(); secondProductA.execute(); secondProductB.execute(); // 产品A3+产品B3 ProductA thirdProductA = Factory3.get().createProductA(); ProductB thirdProductB = Factory3.get().createProductB(); thirdProductA.execute(); thirdProductB.execute(); // 哪怕你有100个地方定义了产品组合,要调整组合的逻辑,只要修改一个工厂就可以了 } public interface ProductA { void execute(); } public static class ProductA1 implements ProductA { public void execute() { System.out.println("产品A1的功能逻辑"); } } public static class ProductA2 implements ProductA { public void execute() { System.out.println("产品A2的功能逻辑"); } } public static class ProductA3 implements ProductA { public void execute() { System.out.println("产品A3的功能逻辑"); } } public interface ProductB { void execute(); } public static class ProductB1 implements ProductB { public void execute() { System.out.println("产品B1的功能逻辑"); } } public static class ProductB2 implements ProductB { public void execute() { System.out.println("产品B2的功能逻辑"); } } public static class ProductB3 implements ProductB { public void execute() { System.out.println("产品B3的功能逻辑"); } } public interface Factory { ProductA createProductA(); ProductB createProductB(); } public static class Factory1 implements Factory { private static final Factory1 instance = new Factory1(); private Factory1() {} public static Factory1 get() { return instance; } public ProductA createProductA() { return new ProductA1(); } public ProductB createProductB() { //return new ProductB1(); return new ProductB3(); } } public static class Factory2 implements Factory { private static final Factory2 instance = new Factory2(); private Factory2() {} public static Factory2 get() { return instance; } public ProductA createProductA() { return new ProductA2(); } public ProductB createProductB() { return new ProductB2(); } } public static class Factory3 implements Factory { private static final Factory3 instance = new Factory3(); private Factory3() {} public static Factory3 get() { return instance; } public ProductA createProductA() { return new ProductA3(); } public ProductB createProductB() { return new ProductB3(); } } }
那这个时候,就是说,哪怕你有100个地方,定义了这个产品组合。要调整组合的这个逻辑,只要修改这一个工厂就可以了,这个工厂,就可以认为是抽象工厂的这么一个模式。那么像抽象工厂这个模式,它就更复杂了,在实际的开发场景里面,就更少见了。
抽象工厂模式的应用:
但是我们这个做电商的项目,实际在这个里面,抽象工厂模式 会跟这个 策略模式 结合起来,再加上实际的电商业务,去实践。
所以,从模板方法,简单工厂,到工厂方法,再到 抽象工厂模式,在电商项目中,抽象工厂模式,加策略模式,再加电商业务,你会发现一点。就是说,像这种设计模式,它是高度提炼的这个东西,如果 不放到项目里面去,只是通过一个一个demo,知道这个模式长什么样,光会demo的话,是没有用的。要想真正掌握,这个模式就必须在实际的这个系统里面去做,必须在实际的项目里面去实践,然后这样的话,才能掌握说,如果把这个模式应用到复杂的业务场景里面去,然后,去保证我们这个代码设计,是非常的可维护,可扩展。