产品等级结构和产品族

产品等级结构:产品等级结构即产品的继承结构。

产品族:在抽象工厂模式中,产品族是指由同一个工厂生产的位于不同产品等级结构中的一组产品。

抽象工厂模式概述

当系统所提供的工厂生产的具体产品并不是一个简单的对象,而是多个位于不同产品等级结构,属于不同类型的具体产品时就可以使用抽象工厂模式。

抽象工厂模式和工厂方法模式最大的区别在于:工厂方法模式针对的是一个产品的等级结构,而抽象工厂模式需要面对多个产品等级结构,一个工厂等级结构可以负责多个不同产品等级结构中的产品对象的创建。

抽象工厂模式为创建一组对象提供了一种解决方案。与工厂方法模式相比,抽象工厂模式中的抽象具体工厂不只是创建一种产品,它负责创建一族产品。

定义: 提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类。

抽象工厂模式又称为工具模式,它是一种对象创建型模式。

抽象工厂模式结构与实现

抽象工厂模式结构

91c8758da4a3a9397a4baff3c040fde9.png

角色:

AbstractFactory(抽象工厂):它声明了一组用于创建一组产品的方法,每一个方法对应一种产品

ConcreteFactory(具体工厂):它实现了在抽象工厂中声明的创建产品的方法,生成一组具体产品,这些产品构成了一个产品族,每一个产品都位于某个产品等级结构中。

AbstractProduct(抽象产品):它为每种产品声明接口,在抽象产品中声明了产品所具有的业务方法

ConcreteProduct(具体产品):它定义具体工厂生产的具体产品对象,实现抽象产品接口中声明的业务方法。

抽象工厂模式的实现

定义抽象产品接口

先为产品族中的每个产品定义抽象接口:

// 抽象冰箱接口
interface Refrigerator {
    void cool(); // 核心功能:制冷
}
 
// 抽象电视接口
interface TV {
    void play(); // 核心功能:播放
}

实现具体产品类

每个具体产品对应一个品牌(产品族):

// 海尔冰箱(具体产品)
class HaierRefrigerator implements Refrigerator {
    @Override
    public void cool() {
        System.out.println("海尔冰箱:智能恒温制冷");
    }
}
 
// 美的冰箱(具体产品)
class MideaRefrigerator implements Refrigerator {
    @Override
    public void cool() {
        System.out.println("美的冰箱:节能静音制冷");
    }
}
 
// 海尔电视(具体产品)
class HaierTV implements TV {
    @Override
    public void play() {
        System.out.println("海尔电视:4K HDR画质");
    }
}
 
// 美的电视(具体产品)
class MideaTV implements TV {
    @Override
    public void play() {
        System.out.println("美的电视:AI语音控制");
    }
}

定义抽象工厂接口

抽象工厂接口声明创建产品族的方法:

interface ApplianceFactory {
    Refrigerator createRefrigerator(); // 创建冰箱
    TV createTV(); // 创建电视
}

实现具体工厂类

每个具体工厂对应一个产品族(品牌):

// 海尔工厂(生产海尔产品族)
class HaierFactory implements ApplianceFactory {
    @Override
    public Refrigerator createRefrigerator() {
        return new HaierRefrigerator();
    }
    @Override
    public TV createTV() {
        return new HaierTV();
    }
}
 
// 美的工厂(生产美的产品族)
class MideaFactory implements ApplianceFactory {
    @Override
    public Refrigerator createRefrigerator() {
        return new MideaRefrigerator();
    }
    @Override
    public TV createTV() {
        return new MideaTV();
    }
}

客户端使用抽象工厂

客户端通过抽象工厂接口获取产品族,无需依赖具体类:

public class Client {
    public static void main(String[] args) {
        // 选择海尔产品族
        ApplianceFactory factory = new HaierFactory();
        Refrigerator fridge = factory.createRefrigerator();
        TV tv = factory.createTV();
        fridge.cool(); // 输出:海尔冰箱:智能恒温制冷
        tv.play();     // 输出:海尔电视:4K HDR画质
 
        // 切换到美的产品族(仅需修改工厂实例)
        factory = new MideaFactory();
        fridge = factory.createRefrigerator();
        tv = factory.createTV();
        fridge.cool(); // 输出:美的冰箱:节能静音制冷
        tv.play();     // 输出:美的电视:AI语音控制
    }
}

开闭原则的倾斜性

在抽象工厂模式中增加新的产品族很方便,但是新增新的产品等级结构很麻烦,抽象工厂的这种性质称为开闭原则的倾斜性。

抽象工厂模式的优缺点

优点

  1. 隔离具体类:客户端无需知道产品的具体类名,降低耦合度。
  2. 易交换产品族:更换具体工厂即可切换整个产品族(如海尔→美的)。
  3. 保证产品一致性:同一工厂创建的产品属于同一产品族,确保协同工作。

缺点

  1. 扩展新产品困难:新增产品(如洗衣机)需修改抽象工厂接口及所有具体工厂,违反“开闭原则”。
  2. 类数量膨胀:产品族和工厂增多会导致类数量急剧增加,维护成本上升。

应用场景

  • 系统需独立于产品创建:客户端不关心产品如何生成,只需使用产品族。
  • 产品族协同使用:产品族内的产品必须一起工作(如海尔冰箱+海尔电视)。
  • 多产品族配置:系统可根据需求切换不同产品族(如家电品牌切换)。