GOF设计模式-创建型模式-抽象工厂模式

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

 

ps:重点:产品族的概念 ;

先上定义:

 

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

这个是不是有点儿乱  我们看下它的结构图先:

分析一波:

1.客户端需要 产品AbstractProductA 和AbstractProductB  所以他要找一个能生产AbstractProductA 和AbstractProductB  的工厂 Factory (不知道是哪个工厂);

2.后来发现有两个工厂能生产这两个产品:ConcreteFactory1 和 ConcreteFactory2;

3.这两个工厂对A、B两种产品有着不同的实现工艺:

   ConcreteFactory1 :ConcreteProductA1、ConcreteProductB1

   ConcreteFactory2 :ConcreteProductA2、ConcreteProductB2

在抽象工厂模式结构图中包含如下几个角色:

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

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

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

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

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

 

看明白了他的套路 我们来举个栗子:

 

Sunny软件公司欲开发一套界面皮肤库,

可以对Java桌面软件进行界面美化。

为了保护版权, 该皮肤库源代码不打算公开,而只向用户提供已打包为jar文件的class字节码文件。

用户在使 用时可以通过菜单来选择皮肤,不同的皮肤将提供视觉效果不同的按钮、文本框、组合框等 界面元素,

该皮肤库需要具备良好的灵活性和可扩展性,用户可以自由选择不同的皮肤,开发人员可以 在不修改既有代码的基础上增加新的皮肤。

需求图:

看看用抽象工厂模式我们怎么解决它:

UML结构图:

上代码:

//在本实例中我们对代码进行了大量简化,实际使用时,界面组件的初始化代码较为复杂,还需要使用JD //按钮接口:抽象产品
interface Button {
    public void display();
}
//Spring按钮类:具体产品
class SpringButton implements Button {
    public void display() {
        System.out.println("显示浅绿色按钮。");
    }
}
//Summer按钮类:具体产品
class SummerButton implements Button {
    public void display() {
        System.out.println("显示浅蓝色按钮。");
    }
}
//文本框接口:抽象产品
interface TextField {
    public void display();
}
//Spring文本框类:具体产品
class SpringTextField implements TextField {
    public void display() {
        System.out.println("显示绿色边框文本框。");
    }
}
//Summer文本框类:具体产品
class SummerTextField implements TextField {
    public void display() {
        System.out.println("显示蓝色边框文本框。");
    }
}
//组合框接口:抽象产品
interface ComboBox {
    public void display();
}
//Spring组合框类:具体产品
class SpringComboBox implements ComboBox {
    public void display() {
        System.out.println("显示绿色边框组合框。");
    }
}
//Summer组合框类:具体产品
class SummerComboBox implements ComboBox {
    public void display() {
        System.out.println("显示蓝色边框组合框。");
    }
}
//界面皮肤工厂接口:抽象工厂
interface SkinFactory {
    public Button createButton();
    public TextField createTextField();
    public ComboBox createComboBox();
}
//Spring皮肤工厂:具体工厂
class SpringSkinFactory implements SkinFactory {
    public Button createButton() {
        return new SpringButton();
    }
    public TextField createTextField() {
        return new SpringTextField();
    }
    public ComboBox createComboBox() {
        return new SpringComboBox();
    }
}
//Summer皮肤工厂:具体工厂
class SummerSkinFactory implements SkinFactory {
    public Button createButton() {
        return new SummerButton();
    }
    public TextField createTextField() {
        return new SummerTextField();
    }
    public ComboBox createComboBox() {
        return new SummerComboBox();
    }
}
class Client {
    public static void main(String args[]) {
        //使用抽象层定义
        SkinFactory factory;
        Button bt;
        TextField tf;
        ComboBox cb;
        factory = new SpringSkinFactory();
        bt = factory.createButton();
        tf = factory.createTextField();
        cb = factory.createComboBox();
        bt.display();
        tf.display();
        cb.display();
    }
}
}

看完代码我们发现 切换皮肤很方便 开发新皮肤也很方便 。

但是如果我们现在想给一个新的元素加皮肤,比如单选按钮。我们会发现  每一种皮肤都要维护自己的皮肤工厂,来实现单选渲染逻辑。这违背了开闭原则。我们的新需求改动了几乎所有的抽象工厂代码。

怎么办? 没法办,这也是抽象工厂最大的缺点。

在抽象工 厂模式中,增加新的产品族很方便,但是增加新的产品等级结构很麻烦,抽象工厂模式的这 种性质称为“开闭原则”的倾斜性。也就是说需要设计之初考虑全面,减少增加新的产品结构的操作。

抽象工厂方法总结:

 

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

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

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

(3) 增加新的产品族很方便,无须修改已有系统,符合“开闭原则”。

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

增加新的产品等级结构麻烦,需要对原有系统进行较大的修改,甚至需要修改抽象层代码, 这显然会带来较大的不便,违背了“开闭原则”。

1. 适用场景 在以下情况下可以考虑使用抽象工厂模式:

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

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

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

(4) 产品等级结构稳定,设计完成之后,不会向系统中增加新的产品等级结构或者删除已有的 产品等级结构。 



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值