设计模式-抽象工厂

抽象工厂模式:

最复杂的 工厂模式的变种

抽象工厂模式,叫做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的话,是没有用的。要想真正掌握,这个模式就必须在实际的这个系统里面去做,必须在实际的项目里面去实践,然后这样的话,才能掌握说,如果把这个模式应用到复杂的业务场景里面去,然后,去保证我们这个代码设计,是非常的可维护,可扩展。

end

posted @ 2022-07-19 15:55  HarryVan  阅读(52)  评论(0编辑  收藏  举报