源码分析设计模式之工厂模式(三、抽象工厂模式)

上篇文章讲到了对工厂方法模式进行变化后带来的缺陷,而为了解决工厂方法模式所带来的缺陷,从而引出了抽象工厂模式。

工厂方法模式中具体工厂负责生产具体的产品,每一个具体工厂对应一种具体产品,工厂方法具有唯一性。一般情况下,一个具体工厂中只有一个或者一组重载的工厂方法。但是有时候我们希望一个工厂可以提供多个产品对象,而不是单一的产品对象,如一个电器工厂,它可以生产电视机、电冰箱、空调等多种电器,而不是只生产某一种电器。为了更好地理解抽象工厂模式,先引入两个概念:
  • 产品等级:就好比一个抽象类是手机,其子类有苹果、小米、华为,而抽象类手机与具体品牌的手机之间就构成了一个产品等级结构
  • 产品簇:产品簇是指由同一个工厂生产的,位于不同产品等级结构中的一组产品,如苹果工厂生产的苹果手机、苹果电脑,苹果手机位于手机产品等级结构中,苹果电脑位于电脑产品等级结构中,苹果手机和苹果电脑就构成了一个产品簇

三、抽象工厂模式

抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂来创建其他工厂,该超级工厂又称为其他工厂的工厂。它提供了一种创建对象的最佳方式
在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象
抽象工厂模式可以理解为将简单工厂模式和工厂方法模式进行整合。从设计层面看,抽象工厂模式就是对简单工厂模式的改进(或者称为进一步的抽象)
简单理解:工厂方法模式的工厂是产品等级工厂,因为它们只创建产品等级。就好比手机工厂它只负责创建手机。而在抽象工厂模式中的工厂则是产品簇工厂,它们负责创建产品簇,就好比苹果工厂,它会创建手机、电脑等
/* ----------------------- 服务端 ----------------------- */
/**
 * 食物抽象产品
 */
interface Food {
    
    
    void production();
}

/**
 * 具体产品
 */
class HanBao implements Food {
    
    
    @Override
    public void production() {
    
    
        System.out.println("生产的汉堡包咯");
    }
}

class Xiaolongxia implements Food {
    
    
    @Override
    public void production() {
    
    
        System.out.println("生产的小龙虾咯");
    }
}

/**
 * 添加产品等级
 * 喝的抽象产品
 */
interface Drink {
    
    
    public void drink();
}

class Cola implements Drink {
    
    
    @Override
    public void drink() {
    
    
        System.out.println("可乐好喝。。");
    }
}

class Beer implements Drink {
    
    
    @Override
    public void drink() {
    
    
        System.out.println("夏天喝啤酒最爽了。。");
    }
}

/*
 * 抽象工厂
 */
interface Factory {
    
    
   public Food getFood();
   
   public Drink getDrink();
}

/**
 * 宵夜工厂
 */
class XiaoYeFactory implements Factory {
    
    
    @Override
    public Food getFood() {
    
    
        return new Xiaolongxia();
    }
	
    @Override
    public Drink getDrink() {
    
    
        return new Beer();
    }
}

/**
 * KFC 工厂
 */
class KFCFactory implements  Factory {
    
    
    @Override
    public Food getFood() {
    
    
        return new HanBao();
    }
	
    @Override
    public Drink getDrink() {
    
    
        return new Cola();
    }
}
/* ----------------------- 服务端 ----------------------- */

这个时候如果要增加产品等级,我们只需要新增工厂类和产品类即可
抽象工厂模式

使用场景: QQ 换皮肤,一整套一起换。 生成不同操作系统的程序
抽象工厂模式的优点
  • 它依然具备简单工厂模式工厂方法模式的优点
  • 抽象工厂模式减少了工厂类,无论有多少的产品等级,工厂就一套
  • 当一个产品簇中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品簇中的对象
抽象工厂模式的缺点
  • 产品族扩展非常困难,要增加一个系列的某一产品,既要在抽象的工厂里加代码,又要在具体的工厂里面加代码,这样就违反了设计原则中的开封原则

总结

  • 产品等级比较固定,考虑抽象工厂模式
  • 产品等级经常变化则不建议抽象工厂模式
  • 产品等级少则建议工厂方法模式
  • 工厂模式的意义
    将实例化对象的代码提取出来,放到一个类中统一管理和维护,达到和主项目的依赖关系解耦,从而提高项目的扩展性和维护性
  • 设计模式的 “依赖抽象” 原则
    创建对象实例时,不要直接 new,而是把这个 new 的动作放在一个工厂的方法中并返回,还有的说法是变量不要直接持有具体类的引用
    • 不要让类继承具体类,而是继承抽象类或者是实现接口,因为接口比具体类更稳定
    • 不要覆盖基类中已经实现的方法
  • 创建型模式对于调用者来说,隐藏了复杂的逻辑处理过程, 流水线生产

Guess you like

Origin blog.csdn.net/qq_39249094/article/details/117635211