【设计模式-5】抽象工厂模式的代码实现及使用场景

2024-01-08 22:39:54

?前面我们了解到工厂方法模式通过引入抽象工厂的概念,使得产品对象的创建可以依赖于具体工厂,但是这种设计模式最大的问题是会造成类的数量爆炸式增长。对于这个问题,抽象工厂模式通过引入两个新的概念:产品等级与产品簇,来解决工厂方法的工厂类过多的问题。

?在正式进入抽象工厂模式学习之前,我们先来了解一下这两个概念:

  • 产品等级(分类): 产品等级可以理解为一类相同的产品,可以理解为抽象产品下的子类实现。具体表现为,比如电视机是一类产品,可以有海尔电视机、小米电视机、TCL电视机等,这个电视系列就可以理解为一个产品等级。
  • 产品簇: 产品簇可以理解为一组不同等级产品的组合,但是这些产品都是一个工厂的产品。具体表现为,比如海尔工厂生产电视机、电冰箱、洗衣机等,这些海尔生产的电器产品组合在一起形成一个产品簇。
    在这里插入图片描述

1. 概述

?抽象工厂模式:为创建一组对象提供了一种解决方案,与工厂方法模式相比,抽象工厂模式中的工厂角色不只创建一种产品,而是负责一个产品簇对象的生产。抽象工厂模式是一种创建型的设计模式。
?在抽象工厂模式中,包含4个角色:

  • 抽象工厂角色: 它声明了一组用于创建一个产品簇的方法,每个方法对应一种产品,它可以是接口或者抽象类。
  • 具体工厂角色: 它实现了在抽象工厂中声明的创建具体产品的方法,生成一组具体的产品,这些产品组成一个产品簇,每种产品都属于一个产品等级。
  • 抽象产品角色: 它是每种产品的抽象,可以是接口或者抽象类,声明产品的业务方法。
  • 具体产品角色: 它继承抽象产品,实现了抽象产品中声明的业务方法,多个具体产品可以组成一个产品簇。

2. 代码实现

?抽象工厂模式是一类比较复杂的对象创建型模式,复杂的地方在于产品簇和产品等级维度的划分,有时候业务界限比较模糊,这些都高度依赖于开发人员的业务素养和代码积累等。

?接下来我们就以刚才海尔、美的工厂生产冰箱和电视机的产品为例子,写一个demo:

  • 抽象的工厂接口
public interface AbstractFactory {
    // 创建电视的方法
    TelevisionProduct createTelevisionProduct();
    // 创建冰箱的方法
    RefrigeratorProduct createRefrigeratorProduct();
}
  • 具体的实现类
/**
 * 美的生产工厂
 */
class MideaFactory implements AbstractFactory {
    // 实现创建电视的方法
    @Override
    public TelevisionProduct createTelevisionProduct() {
        return new MideaTelevisionProduct();
    }
    // 创建冰箱的方法
    @Override
    public RefrigeratorProduct createRefrigeratorProduct() {
        return new MideaRefrigeratorProduct();
    }
}

/**
 * 海尔生产工厂
 */
class HairFactory implements AbstractFactory {
    // 实现创建电视的方法
    @Override
    public TelevisionProduct createTelevisionProduct() {
        return new HairTelevisionProduct();
    }
    // 创建冰箱的方法
    @Override
    public RefrigeratorProduct createRefrigeratorProduct() {
        return new HairRefrigeratorProduct();
    }
}
  • 抽象的产品角色
// 产品簇-冰箱产品
public interface RefrigeratorProduct {
    void displayColor();
}

// 产品簇-电视机产品
public interface TelevisionProduct {
    void displayShape();
}
  • 具体的产品角色
// 海尔冰箱
public class HairRefrigeratorProduct implements RefrigeratorProduct {
    @Override
    public void displayColor() {
        System.out.println("海尔冰箱");
    }
}
// 海尔电视机
public class HairTelevisionProduct implements TelevisionProduct{
    @Override
    public void displayShape() {
        System.out.println("海尔电视机");
    }
}
// 美的冰箱
public class MideaRefrigeratorProduct implements RefrigeratorProduct {
    @Override
    public void displayColor() {
        System.out.println("美的冰箱");
    }
}
// 美的电视机
public class MideaTelevisionProduct implements TelevisionProduct{
    @Override
    public void displayShape() {
        System.out.println("美的电视机");
    }
}
  • 客户端及运行结果
class Client {
   public static void main(String[] args) {
       // 美的工厂的产品簇
       AbstractFactory mideaFactory = new MideaFactory();
       RefrigeratorProduct mideaRefrigerator = mideaFactory.createRefrigeratorProduct();
       mideaRefrigerator.displayColor();
       TelevisionProduct mideaTelevision = mideaFactory.createTelevisionProduct();
       mideaTelevision.displayShape();

       System.out.println("========分割线========");
       // 海尔工厂的产品簇
       HairFactory hairFactory = new HairFactory();
       RefrigeratorProduct hairRefrigerator = hairFactory.createRefrigeratorProduct();
       hairRefrigerator.displayColor();
       TelevisionProduct hairTelevision = hairFactory.createTelevisionProduct();
       hairTelevision.displayShape();
   }
}
美的冰箱
美的电视机
========分割线========
海尔冰箱
海尔电视机

3. UML类图

?基于上面的这个抽象工厂的Demo,我们来画一下抽象工厂模式的UML类图。

在这里插入图片描述

4. 总结

?抽象工厂模式是工厂方法模式的进一步延伸,在一些框架和API的类库设计中都得到了广泛的使用。下面,我们来总结一下这种设计模式的优缺点

4.1 优点

  • 对象的创建和使用过程分离,用户无需关注对象的创建,只需要会使用工厂模式即可;
  • 抽象工厂模式使得同一个产品簇的对象可以同时被创建,可以使得用户能同时使用这一个产品簇的对象;
  • 产品簇维度的扩展很方便,直接增加实现即可,符合开闭原则。

4.2 缺点

?抽象工作的缺点也很明显,像扩展产品分类是比较麻烦的,涉及到多个接口和类的关联修改,违背了开闭原则。

文章来源:https://blog.csdn.net/qq_35850405/article/details/128391278
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。