设计模式 - 抽象工厂模式

本文深入解析抽象工厂模式,探讨其与工厂方法模式的区别,并通过示例代码展示如何创建一系列相关或相互依赖的对象,同时讨论了该模式的优点、缺点及适用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一. 简述

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

比如每个抽象产品角色都有两个具体产品。抽象工厂模式提供两个具体工厂角色,分别对应于这两个具体产品角色,每一个具体工厂角色只负责某一个产品角色的实例化。每一个具体工厂类只负责创建抽象产品的某一个具体子类的实例。

属于创建型模式


工厂方法模式 vs 抽象工厂模式

抽象工厂模式是工厂方法模式的升级版本,他与工厂方法模式的区别就在于,工厂方法模式针对的是一个产品等级结构;而抽象工厂模式则是针对的多个产品等级结构。在编程中,通常一个产品结构,表现为一个接口或者抽象类,也就是说,工厂方法模式提供的所有产品都是衍生自同一个接口或抽象类,而抽象工厂模式所提供的产品则是衍生自不同的接口或抽象类。


二. 组成

  • 抽象工厂(Abstract Factory)角色担任这个角色的是工厂方法模式的核心,它是与应用系统商业逻辑无关的。
  • 具体工厂(Concrete Factory)角色这个角色直接在客户端的调用下创建产品的实例。这个角色含有选择合适的产品对象的逻辑,而这个逻辑是与应用系统的商业逻辑紧密相关的。
  • 抽象产品(Abstract Product)角色担任这个角色的类是工厂方法模式所创建的对象的父类,或它们共同拥有的接口。
  • 具体产品(Concrete Product)角色抽象工厂模式所创建的任何产品对象都是某一个具体产品类的实例。这是客户端最终需要的东西,其内部一定充满了应用系统的商业逻辑。

三. UML类图


四. 基本代码

//两种抽象产品:水果、蔬菜
public interface Fruit{}
public interface Veggie{}

//四种具体产品:北方水果,热带水果,北方蔬菜,热带蔬菜
// Northern Fruit
public class NorthernFruit implements Fruit{
    private String name;
    public NorthernFruit(String name)
    {}

    public String getName(){
        return name;
    }

    public void setName(String name){
        this. name = name;
    }
}

// TropicalFruit
public class TropicalFruit implements Fruit{
    private String name;
    public TropicalFruit(String name)
    {}

    public String getName(){
        return name;
    }

    public void setName(String name){
        this. name = name;
    }
}

// NorthernVeggie
public class NorthernVeggie implements Veggie{
    private String name;
    public NorthernVeggie(String name)
    {}

    public String getName(){
        return name;
    }

    public void setName(String name){
        this. name = name;
    }
}

//TropicalVeggie
public class TropicalVeggie implements Veggie{
    private String name;
    public TropicalVeggie(String name)
    {}

    public String getName(){
        return name;
    }

    public void setName(String name){
        this. name = name;
    }
}

//抽象工厂角色
public interface Gardener{
    public Fruit createFruit(String name);
    public Veggie createVeggie(String name);
}

//具体工厂角色:北方工厂,热带角色
public class NorthernGardener implements Gardener{
    public Fruit createFruit(String name){
        return new NorthernFruit(name);
    }

    public Veggie createVeggie(String name){
        return new NorthernVeggie(name);
    }
}

public class TropicalGardener implements Gardener{
    public Fruit createFruit(String name){
        return new TropicalFruit(name);
    }

    public Veggie createVeggie(String name){
        return new TropicalVeggie(name);
    }
}


五. 优缺点

优点:

  1. 易于交换产品系列,由于具体工厂类在一个应用中只需在初始化的时候出现一次,这就使得改变一个应用的具体工厂变得非常容易,它只需要改变具体工厂即可使用不同的产品配置。
  2. 让具体的创建实例过程与客户端分离,客户端是通过它们的抽象接口操纵实例,产品的具体类名也被具体工厂的实现分离,不会出现在客户代码中。

缺点:

  1. 产品族的扩展将是一件十分费力的事情,假如产品族中需要增加一个新的产品,则几乎所有的工厂类都需要进行修改。所以使用抽象工厂模式时,对产品等级结构的划分是非常重要的。

六. 应用场景

当需要创建的对象是一系列相互关联或相互依赖的产品族时,便可以使用抽象工厂模式。说的更明白一点,就是一个继承体系中,如果存在着多个等级结构(即存在着多个抽象类),并且分属各个等级结构中的实现类之间存在着一定的关联或者约束,就可以使用抽象工厂模式。假如各个等级结构中的实现类之间不存在关联或约束,则使用多个独立的工厂来对产品进行创建,则更合适一点。


七. 注意事项

        无论是简单工厂模式,工厂方法模式,还是抽象工厂模式,他们都属于工厂模式,在形式和特点上也是极为相似的,他们的最终目的都是为了解耦。在使用时,我们不必去在意这个模式到底工厂方法模式还是抽象工厂模式,因为他们之间的演变常常是令人琢磨不透的。经常你会发现,明明使用的工厂方法模式,当新需求来临,稍加修改,加入了一个新方法后,由于类中的产品构成了不同等级结构中的产品族,它就变成抽象工厂模式了;而对于抽象工厂模式,当减少一个方法使的提供的产品不再构成产品族之后,它就演变成了工厂方法模式。

       所以,在使用工厂模式时,只需要关心降低耦合度的目的是否达到了。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值