抽象工厂模式

 

工厂方法模式通过引入工厂等级结构,解决了简单工厂模式中工厂类职责太重的问题,但由于工厂方法模式中的每个工厂只生产一类产品,可能会导致系统中存在大量的工厂类,势必会增加系统的开销。此时可以考虑将一些相关的产品组成一个“产品族”,由同一个工厂来统一生产,这就是抽象工厂模式的基本思想。

首先我们先来学习一些产品等级结构和产品族这两个概念。

1.产品等级结构:产品等级结构即产品的继承结构,例如一个抽象类是电脑,其子类由苹果电脑,华为电脑,小米电脑等,则抽象的电脑与具体品牌的电脑之前就构成了一个产品等级结构,抽象电脑类是父类,而具体的品牌电脑是其子类。

2.产品族:在抽象工厂模式中,产品族是指由同一个工厂生产的,位于不同产品等级结构中的一组产品。例如苹果公司工厂生产的苹果电脑,华为公司工厂生产的华为电脑,小米公司工厂生产的小米电脑位于电脑产品等级结构中;而苹果公司工厂生产的苹果手机,华为公司工厂生产的华为手机,小米公司工厂生产的小米手机位于手机产品等级结构中。由苹果公司工厂生产的苹果电脑,苹果手机组成了一个产品族;华为公司工厂生产的华为电脑,华为手机组成了一个产品族;小米公司工厂生产的小米电脑,小米手机又组成了一个产品族。

产品等级结构和产品族的示意图如下所示:

其中不同颜色的多个正方形,圆形和椭圆形分别构成了3个不同的产品等级结构,而相同颜色的正方形,圆形和椭圆形构成了一个产品族,每一个形状对象都位于某个产品族,并属于某个产品等级结构。

当系统所提供的工厂生产的具体产品并不是一个简单的对象,而是多个位于不同产品等级结构、属于不同类型的具体产品时,就可以使用抽象工厂模式。抽象工厂模式时所有形式的工厂模式中最为抽象和最具一般性的一种形式。抽象工厂模式和工厂方法模式最大的区别在于,工厂方法模式针对的是一个产品等级结构,而抽象工厂模式需要面对多个产品等级结构,一个工厂等级结构可以负责多个不同产品等级结构中的产品对象的创建。当一个工厂等级结构可以创建出分属于不同产品等级结构的一个产品族中的所有对象时,抽象工厂模式比工厂方法模式更为简单,更有效率。

抽象工厂模式的定义如下:

抽象工厂模式(Abstract Factory Pattern):提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。抽象工厂模式又称为Kit模式,它是一种对象创建型模式。

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

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

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

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

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

在抽象工厂类中声明了多个工厂方法,用于创建不同类型的产品,抽象工厂可以时接口,也可以是抽象类或具体类,其UML图如下:


/**
 * 电脑类(抽象产品类)
 */
public interface Computer {

    //业务方法
    void display();

}
/**
 * 苹果电脑类(具体产品类)
 */
public class AppleComputer implements Computer{

    @Override
    public void display() {
        System.out.println("苹果电脑显示");
    }
}
/**
 * 华为电脑类(具体产品类)
 */
public class HuaweiComputer implements Computer{

    @Override
    public void display() {
        System.out.println("华为电脑显示");
    }
}
/**
 * 手机类(抽象产品类)
 */
public interface Phone {

    //业务方法
    void call();
}
/**
 * 苹果手机类(具体产品类)
 */
public class ApplePhone implements Phone {

    @Override
    public void call() {
        System.out.println("苹果手机打电话");
    }
}
/**
 * 华为手机类(具体产品类)
 */
public class HuaweiPhone implements Phone {

    @Override
    public void call() {
        System.out.println("华为手机打电话");
    }
}
/**
 * 抽象工厂类
 */
public interface AbstractFactory {

    //生产电脑
    Computer createComputer();

    //生产手机
    Phone createPhone();
}
/**
 * 苹果工厂(具体工厂类),负责具体苹果产品的生产
 */
public class AppleFactory implements AbstractFactory {

    @Override
    public Computer createComputer() {
        return new AppleComputer();
    }

    @Override
    public Phone createPhone() {
        return new ApplePhone();
    }
}
/**
 * 华为工厂(具体工厂类),负责具体华为产品的生产
 */
public class HuaweiFactory implements AbstractFactory {

    @Override
    public Computer createComputer() {
        return new HuaweiComputer();
    }

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

抽象工厂模式的主要优点如下:

1.抽象工厂模式隔离了具体类的生成,使得客户并不需要知道什么被创建。由于这种隔离,更换一个具体工厂就变得相对容易,所有的具体工厂都实现了在抽象工厂中声明的那些公共接口,因此只需改变具体工厂的实例,就可以在某种程度上改变整个软件系统的行为;

2.当一个产品族中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一个产品族中的对象;

3.增加信息的产品族很方便,无须修改已有系统,符合开闭原则。

抽象工厂模式的主要缺点如下:

抽象工厂模式主要的缺点就是:增加新的产品等级结构很麻烦,需要对原有系统进行较大的修改,甚至需要修改抽象层的代码,这显然会带来较大的不便,违背了开闭原则。

抽象工厂模式的主要适用场景如下:

1.一个系统不应当依赖于产品类的实例如何被创建、组合和表达的细节,对于所有类型的工厂模式都是很重要的,用户无须对象的创建过程,将对象的创建和使用解耦;

2.系统中有多于一个的产品族,而每次只使用其中某一个产品族。可以通过配置文件等方式来使得用户可以动态改变产品族,也可以很方便地增加新的产品族;

3。属于同一个产品族地产品将在一起使用,这一约束必须在系统地设计中体现出来。同一个产品族中地产品可以是没有任何关系地对象,但它们都具有一些共同地约束,例如同一个操作系统下地按钮和文本框,按钮和文本框之间没有直接关系,但它们都属于某一操作系统,此时具有一个共同地约束条件:操作系统地类型;

4.产品等级结构文档,设计完成之后,不会向系统中增加新的产品等级结构或者删除已有地产品等级结构。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章