抽象工厂模式(Abstract Factory Pattern)

一、抽象工厂模式

介绍

抽象工厂模式是一种创建型设计模式,它提供了一种将一组相关的对象创建过程封装在一个工厂接口中的方式。抽象工厂模式可以创建一系列相互依赖或相互关联的对象,而无需指定其具体的类。

抽象工厂模式通过引入抽象工厂和具体工厂来实现对象的创建和管理。抽象工厂定义了一组创建产品的方法,每个方法对应一个具体的产品族。具体工厂实现了抽象工厂中的方法,负责创建具体的产品对象。

抽象工厂模式可以帮助我们将客户端代码与具体产品的创建过程解耦,使得客户端代码只需关注抽象工厂和抽象产品的接口,而无需关注具体的产品类。这样可以提高代码的可扩展性和可维护性。

结构

抽象工厂模式包含以下几个角色:

  • 抽象工厂(Abstract Factory):声明一组创建产品的方法,每个方法对应一个具体产品族。
  • 具体工厂(Concrete Factory):实现抽象工厂中的方法,负责创建具体的产品对象。
  • 抽象产品(Abstract Product):定义产品的共同接口,具体产品类都实现了这个接口。
  • 具体产品(Concrete Product):实现抽象产品接口的具体产品。

下面是一个简单的类图示例:

+------------------------+
|     AbstractFactory    |
+------------------------+
| + createProductA()     |
| + createProductB()     |
+------------------------+

        ^               ^
        |               |
        
+------------------------+
|   ConcreteFactory1     |
+------------------------+
| + createProductA()     |
| + createProductB()     |
+------------------------+

        ^               ^
        |               |
        
+------------------------+
|   ConcreteFactory2     |
+------------------------+
| + createProductA()     |
| + createProductB()     |
+------------------------+


        ^               ^
        |               |
        
+------------------------+
|     AbstractProductA   |
+------------------------+
| + operation()          |
+------------------------+

        ^               ^
        |               |
        
+------------------------+
|     AbstractProductB   |
+------------------------+
| + operation()          |
+------------------------+

        ^               ^
        |               |
        
+------------------------+
|   ConcreteProductA1    |
+------------------------+
| + operation()          |
+------------------------+

        ^               ^
        |               |
        
+------------------------+
|   ConcreteProductA2    |
+------------------------+
| + operation()          |
+------------------------+

        ^               ^
        |               |
        
+------------------------+
|   ConcreteProductB1    |
+------------------------+
| + operation()          |
+------------------------+

        ^               ^
        |               |
        
+------------------------+
|   ConcreteProductB2    |
+------------------------+
| + operation()          |
+------------------------+

示例

假设我们有一个电子产品工厂,可以生产电视和手机,其中电视分为液晶电视和等离子电视,手机分为智能手机和功能手机。我们可以使用抽象工厂模式来创建这些产品对象。

首先,我们定义抽象产品接口 TV 和 Phone

public interface TV {
    void display();
}

public interface Phone {
    void call();
}

然后,我们创建具体的产品类,如 LCDTVPlasmaTVSmartPhone 和 FeaturePhone,它们分别实现了 TV 和 Phone 接口:

public class LCDTV implements TV {
    @Override
    public void display() {
        System.out.println("显示液晶电视");
    }
}

public class PlasmaTV implements TV {
    @Override
    public void display() {
        System.out.println("显示等离子电视");
    }
}

public class SmartPhone implements Phone {
    @Override
    public void call() {
        System.out.println("拨打智能手机电话");
    }
}

public class FeaturePhone implements Phone {
    @Override
    public void call() {
        System.out.println("拨打功能手机电话");
    }
}

接下来,我们创建抽象工厂接口 ElectronicFactory,其中包含创建电视和手机的方法:

public interface ElectronicFactory {
    TV createTV();
    Phone createPhone();
}

然后,我们创建具体的工厂类,如 SonyFactory 和 SamsungFactory,它们分别实现了 ElectronicFactory 接口,并负责创建具体的电视和手机对象:

public class SonyFactory implements ElectronicFactory {
    @Override
    public TV createTV() {
        return new LCDTV();
    }

    @Override
    public Phone createPhone() {
        return new SmartPhone();
    }
}

public class SamsungFactory implements ElectronicFactory {
    @Override
    public TV createTV() {
        return new PlasmaTV();
    }

    @Override
    public Phone createPhone() {
        return new FeaturePhone();
    }
}

最后,我们可以使用抽象工厂来创建和使用电视和手机对象:

public class Main {
    public static void main(String[] args) {
        ElectronicFactory sonyFactory = new SonyFactory();
        TV sonyTV = sonyFactory.createTV();
        Phone sonyPhone = sonyFactory.createPhone();
        sonyTV.display(); // 输出:显示液晶电视
        sonyPhone.call(); // 输出:拨打智能手机电话

        ElectronicFactory samsungFactory = new SamsungFactory();
        TV samsungTV = samsungFactory.createTV();
        Phone samsungPhone = samsungFactory.createPhone();
        samsungTV.display(); // 输出:显示等离子电视
        samsungPhone.call(); // 输出:拨打功能手机电话
    }
}

优点和适用场景

抽象工厂模式具有以下优点:

  • 将对象的创建逻辑推迟到具体工厂类中实现,使得客户端代码与具体产品的创建过程解耦。
  • 可以通过切换具体工厂类来创建不同的产品族,实现了产品族的变化而不影响客户端代码。
  • 具体工厂类可以根据需要返回不同的具体产品对象,实现了多态性。

抽象工厂模式适用于以下场景:

  • 需要创建一系列相互依赖或相互关联的对象。
  • 需要在运行时动态决定具体对象的类型。
  • 客户端不需要知道对象的具体创建过程,只需要知道抽象工厂和抽象产品的接口即可。

二、简单工厂模式、工厂方法模式和抽象工厂模式的比较

简单工厂模式

定义

简单工厂模式是一种创建型设计模式,它通过一个工厂类来创建不同类型的对象,而无需直接暴露对象的创建逻辑给客户端。

结构

简单工厂模式包含以下几个角色:

  • 工厂类(Factory):负责创建对象的工厂类,根据客户端的请求创建相应的对象。
  • 产品类(Product):具体的产品类,实现了工厂类定义的接口或继承了工厂类的抽象类。

工作原理

简单工厂模式的工作原理如下:

  1. 客户端通过调用工厂类的静态方法或实例方法来请求创建某个产品对象。
  2. 工厂类根据客户端的请求,内部使用条件语句或其他方式判断应该创建哪个具体产品对象。
  3. 工厂类创建相应的产品对象并返回给客户端。

优点

  • 将对象的创建逻辑封装在工厂类中,客户端只需通过工厂类来创建对象,无需关心对象的具体创建过程。
  • 简化客户端代码,降低了客户端与具体产品类的耦合度。

缺点

  • 工厂类负责创建所有产品对象,当产品种类较多时,工厂类的代码会变得复杂,违反了开闭原则。
  • 如果需要添加新的产品,需要修改工厂类的代码,违反了开闭原则。

工厂方法模式

定义

工厂方法模式是一种创建型设计模式,它将对象的创建延迟到子类中进行,子类根据需要重写工厂方法来创建具体的对象。

结构

工厂方法模式包含以下几个角色:

  • 抽象工厂(Abstract Factory):声明创建产品的工厂方法,子类必须实现这个方法来创建具体的产品对象。
  • 具体工厂(Concrete Factory):实现抽象工厂中的工厂方法,负责创建具体的产品对象。
  • 抽象产品(Abstract Product):定义产品的共同接口,具体产品类都实现了这个接口。
  • 具体产品(Concrete Product):实现抽象产品接口的具体产品。

工作原理

工厂方法模式的工作原理如下:

  1. 抽象工厂定义了一个工厂方法,用于创建产品对象,该方法返回一个抽象产品类型。
  2. 具体工厂继承抽象工厂,并实现工厂方法,根据需要重写工厂方法来创建具体的产品对象。
  3. 客户端通过调用具体工厂的工厂方法来创建产品对象。

优点

  • 将对象的创建延迟到子类中进行,符合开闭原则,新增产品时只需创建对应的具体工厂和产品类,无需修改已有代码。
  • 客户端只需关心抽象工厂和抽象产品的接口,无需关心具体的工厂和产品类。

缺点

  • 每新增一个产品,都需要创建对应的具体工厂和产品类,导致类的个数增加。

抽象工厂模式

定义

抽象工厂模式是一种创建型设计模式,它提供了一种将一组相关的对象创建过程封装在一个工厂接口中的方式。抽象工厂模式可以创建一系列相互依赖或相互关联的对象,而无需指定其具体的类。

结构

抽象工厂模式包含以下几个角色:

  • 抽象工厂(Abstract Factory):声明一组创建产品的方法,每个方法对应一个具体的产品族。
  • 具体工厂(Concrete Factory):实现抽象工厂中的方法,负责创建具体的产品对象。
  • 抽象产品(Abstract Product):定义产品的共同接口,具体产品类都实现了这个接口。
  • 具体产品(Concrete Product):实现抽象产品接口的具体产品。

工作原理

抽象工厂模式的工作原理如下:

  1. 抽象工厂定义了一组创建产品的方法,每个方法对应一个具体的产品族。
  2. 具体工厂实现了抽象工厂中的方法,负责创建具体的产品对象。
  3. 客户端通过调用具体工厂的方法来创建产品对象。

优点

  • 将对象的创建逻辑封装在具体工厂中,客户端只需通过具体工厂来创建对象,无需关心对象的具体创建过程。
  • 可以通过切换具体工厂类来创建不同的产品族,实现了产品族的变化而不影响客户端代码。

缺点

  • 当需要新增一个产品族时,需要创建对应的具体工厂和产品类,导致类的个数增加。

异同总结

  1. 创建方式不同:简单工厂模式通过一个工厂类来创建对象,工厂方法模式将对象的创建延迟到子类中进行,抽象工厂模式通过一个工厂接口来创建一系列相互关联的对象。
  2. 类的个数不同:简单工厂模式只需要一个工厂类和一组产品类,工厂方法模式需要一个抽象工厂和一组具体工厂和产品类,抽象工厂模式需要一个抽象工厂和一组具体工厂和产品类。
  3. 可扩展性不同:简单工厂模式和抽象工厂模式在新增产品时需要修改工厂类的代码,工厂方法模式通过新增具体工厂和产品类来实现扩展。
  4. 关注点不同:简单工厂模式和抽象工厂模式将对象的创建逻辑封装在工厂类中,客户端只需通过工厂类来创建对象,工厂方法模式将对象的创建逻辑延迟到子类中进行。

公众号请关注"果酱桑", 一起学习,一起进步!

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值