设计模式之抽象工厂

简介: 设计模式之抽象工厂

一、介绍

抽象工厂模式(Abstract Factory Pattern)属于创建型设计模式。用于解决比工厂方法设计模式更加复杂的问题。

复杂到哪里了呢?

我们将抽象工厂模式和工厂模式进行简单的比较,或许可以有更好的理解:

  • 工厂方法设计模式中,指定工厂只能创建对应的单个产品,是一对一的关系。
  • 抽象工厂模式中,不仅需要创建产品的工厂,还多了一个创建工厂的工厂(顶级工厂)。当顶级工厂创建一个工厂时,顶级工厂与工厂是一对一的关系(等同于工厂模式),被创建的工厂可以生产多个产品,因此顶级工厂与产品之间是一对多的关系。

二、基本组件

在我们使用抽象工厂设计模式时,一般需要以下组件:

  • 抽象工厂
  • 工厂实现
  • 抽象产品
  • 产品实现

一般来讲,从抽象工厂中获取的对象类型为抽象类型,其具体类型由具体的工厂实现决定。

三、演示案例

唉,到了结婚的年纪了,我们就以结婚为例吧。

1. 定义抽象工厂

结婚是一件十分麻烦的事情,需要准备非常非常多的事情,比如婚车婚房婚纱照等等。所以我们以结婚为工厂,以婚车婚房婚纱照为产品。先对结婚这件事情做一个规范的定义。

  public interface MarriageFactory {
   
   
      /**
       * 产品 - 婚车
       */
      Car getCar();
      /**
       * 产品 - 婚房
       */
      House getHouse();
      /**
       * 产品 - 婚纱照
       */
      Picture getPicture();
  }

2. 定义抽象产品

  • 婚车

    public interface Car {
         
         
    
        /**
         * 坐婚车
         */
        void drive();
    }
    
  • 婚房

    public interface House {
         
         
        /**
         * 买房
         */
        void buyHouse();
    }
    
  • 婚纱照

    public interface Picture {
         
         
    
        /**
         * 照相
         */
        void takePicture();
    }
    

3. 定义具体工厂

我们结婚一般都是要找一个婚庆公司,假设婚庆公司都提供结婚的一条龙服务,包括婚车、婚房、婚纱照等业务,现在我们城里有两家婚庆公司:汤姆婚庆(TomFactory)杰瑞婚庆(JerryFactory)

  • 汤姆婚庆(TomFactory)

    汤姆婚庆公司提供具有汤姆特色的业务,如汤姆婚车(TomCar)汤姆婚房(TomHouse)汤姆照相(TomPicture)

    public class TomFactory implements MarriageFactory {
         
         
        public TomFactory() {
         
         
            System.out.println("选择了汤姆婚庆公司");
        }
    
        @Override
        public Car getCar() {
         
         
            return new TomCar();
        }
    
        @Override
        public House getHouse() {
         
         
            return new TomHouse();
        }
    
        @Override
        public Picture getPicture() {
         
         
            return new TomPicture();
        }
    }
    
  • 杰瑞婚庆(JerryFactory)

    杰瑞婚庆公司提供具有杰瑞特色的业务,如杰瑞婚车(TomCar)杰瑞婚房(TomHouse)杰瑞照相(TomPicture)

    public class JerryFactory implements MarriageFactory {
         
         
        public JerryFactory() {
         
         
            System.out.println("选择了杰瑞婚庆公司");
        }
    
        @Override
        public Car getCar() {
         
         
            return new JerryCar();
        }
    
        @Override
        public House getHouse() {
         
         
            return new JerryHouse();
        }
    
        @Override
        public Picture getPicture() {
         
         
            return new JerryPicture();
        }
    }
    

4. 定义具体产品

  • 汤姆婚庆公司提供具有汤姆特色的业务,如汤姆婚车(TomCar)汤姆婚房(TomHouse)汤姆照相(TomPicture)

    public class TomCar implements Car{
         
         
        /**
         * 婚车
         */
        @Override
        public void drive() {
         
         
            System.out.println("汤姆婚车开起来...");
        }
    }
    
    public class TomHouse implements House{
         
         
    
        /**
         * 买房
         */
        @Override
        public void buyHouse() {
         
         
            System.out.println("汤姆一品房价50w.....");
        }
    }
    
    public class TomPicture implements Picture{
         
         
    
        /**
         * 照相
         */
        @Override
        public void takePicture() {
         
         
            System.out.println("汤姆照相馆照相.....");
        }
    }
    
  • 杰瑞婚庆公司提供的业务具有杰瑞特色,如杰瑞婚车(TomCar)杰瑞婚房(TomHouse)杰瑞照相(TomPicture)

    public class JerryCar implements Car{
         
         
        /**
         * 婚车
         */
        @Override
        public void drive() {
         
         
            System.out.println("杰瑞婚车开起来...");
        }
    }
    
    public class JerryHouse implements House{
         
         
    
        /**
         * 买房
         */
        @Override
        public void buyHouse() {
         
         
            System.out.println("杰瑞一品房价30w...");
        }
    }
    
    public class JerryPicture implements Picture{
         
         
    
        /**
         * 照相
         */
        @Override
        public void takePicture() {
         
         
            System.out.println("杰瑞照相馆照相.....");
        }
    }
    

5. 代码演示

下面我们对上述案例进行代码演示

  • 选择杰瑞婚庆公司

    public static void main(String[] args) {
         
         
    
        // 选择杰瑞婚庆公司
        MarriageFactory factory = new JerryFactory();
        Car car = factory.getCar();
        House house = factory.getHouse();
        Picture picture = factory.getPicture();
    
        car.drive();
        house.buyHouse();
        picture.takePicture();
    }
    

    输出结果:

    结果1.jpg

  • 选择汤姆婚庆公司

    public static void main(String[] args) {
         
         
    
        // 选择杰瑞婚庆公司
        MarriageFactory factory = new TomFactory();
        Car car = factory.getCar();
        House house = factory.getHouse();
        Picture picture = factory.getPicture();
    
        car.drive();
        house.buyHouse();
        picture.takePicture();
    }
    

    输出结果:

    结果2.jpg

6. 代码改造

在上面的测试代码中我们注意到,我们只是对new婚庆公司的实际类型做了修改,而产品相关代码没有任何改动。于是我们可以将对婚庆公司的实例化过程按照工厂方法设计模式那样转移到工厂中,只需要抽象工厂根据传入的参数返回不同的工厂实例即可。

  • 在抽象工厂中添加静态方法getInstance() 和 枚举类MarriageType

    static MarriageFactory getInstance(MarriageType type) {
         
         
        if (type.equals(MarriageType.JERRY)) {
         
         
            return new JerryFactory();
        }
        return new TomFactory();
    }
    
    enum MarriageType {
         
         
        JERRY,
        TOM;
    }
    
  • 修改测试代码

    public static void main(String[] args) {
         
         
    
        // 选择杰瑞婚庆公司
        MarriageFactory factory = MarriageFactory.getInstance(MarriageFactory.MarriageType.JERRY);
        Car car = factory.getCar();
        House house = factory.getHouse();
        Picture picture = factory.getPicture();
    
        car.drive();
        house.buyHouse();
        picture.takePicture();
    }
    

另外,在静态方法getInstance() 中,我们可以再次结合单例模式来避免频繁实例化婚庆公司对象。

四、总结

  • 抽象工厂与工厂方法的最主要区别就是:抽象工厂允许创建多个产品;而工厂方法只允许创建一个产品
  • 该设计模式有一个致命缺点:每当我们在工厂中添加新的产品时,工厂的抽象和具体实现都需要修改。当工厂的具体实现较多时,每一个实现都必须适配新添加的产品。




纸上得来终觉浅,绝知此事要躬行。

————————我是万万岁,我们下期再见————————

相关文章
|
3月前
|
设计模式 Java
常用设计模式(工厂方法,抽象工厂,责任链,装饰器模式)
有关设计模式的其他常用模式请参考 单例模式的实现 常见的设计模式(模板与方法,观察者模式,策略模式)
39 2
|
6月前
|
设计模式 Java 关系型数据库
解锁设计模式的神秘面纱:编写无懈可击的代码之抽象工厂设计模式
解锁设计模式的神秘面纱:编写无懈可击的代码之抽象工厂设计模式
23 0
|
3月前
|
设计模式
设计模式-抽象工厂
设计模式-抽象工厂
|
6月前
|
设计模式 架构师
设计模式之抽象工厂
设计模式之抽象工厂
|
1月前
|
设计模式 关系型数据库 数据库
【C++ 设计模式 工厂模式对比】深入探索设计模式:工厂方法与抽象工厂的比较与对照
【C++ 设计模式 工厂模式对比】深入探索设计模式:工厂方法与抽象工厂的比较与对照
21 1
|
3月前
|
设计模式 Java 数据库连接
Java设计模式--简单工厂、工厂方法和抽象工厂之间的区别
设计模式中的工厂模式(Factory Design pattern)是一个比较常用的创建型设计模式,其中可以细分为三种:简单工厂(Simple Factory)、工厂方法(Factory Method)和抽象工厂(Abstract Factory)。那么三者有什么区别呢?
99 1
Java设计模式--简单工厂、工厂方法和抽象工厂之间的区别
|
3月前
|
设计模式 安全 数据库
创建型设计模式-单例模式/工厂模式/抽象工厂
创建型设计模式-单例模式/工厂模式/抽象工厂
37 0
|
9月前
|
设计模式 前端开发 JavaScript
前端实现设计模式之抽象工厂
抽象工厂模式(Abstract Factory Pattern)是一种创建型设计模式,它提供了一种创建一系列相关或相互依赖对象的接口,而无需指定具体的类。抽象工厂模式可以帮助我们实现对象的创建与使用的解耦,同时提供了一种灵活的方式来创建不同产品族的对象。本文将介绍如何在前端中实现抽象工厂模式,并提供具体的代码示例和解读。
|
4月前
|
设计模式 SQL 数据库连接
设计模式之抽象工厂模式--创建一系列相关对象的艺术(简单工厂、工厂方法、到抽象工厂的进化过程,类图NS图)
设计模式之抽象工厂模式--创建一系列相关对象的艺术(简单工厂、工厂方法、到抽象工厂的进化过程,类图NS图)
|
7月前
|
设计模式 Go iOS开发
23种设计模式漫画版系列—抽象工厂
23种设计模式漫画版系列—抽象工厂
42 0