设计模式学习笔记(六):抽象工厂模式

1 相关术语

在了解抽象工厂模式以前,首先来了解一下两个术语:java

  • 产品等级结构
  • 产品族

1.1 产品等级结构

产品等级结构也就是产品的继承结构,例如一个抽象类是电视机,子类有不一样品牌的电视机,好比海尔电视机,海信电视机,TCL电视机,而抽象电视机与具体品牌的电视机之间构成了一个产品等级结构,抽象电视机是父类,而具体品牌的电视机是子类。ide

1.2 产品族

产品族是指由一个同一个工厂产生的位于不一样产品等级结构中的一组产品,例如海尔电器工厂生产的海尔电视机,海尔电冰箱。海尔电视机位于电视机产品等级结构中,海尔电冰箱位于电冰箱产品等级结构中,海尔电视机与海尔电冰箱共同构成了一个产品族。测试

二者示意图以下:设计

在这里插入图片描述

2 抽象工厂模式

抽象工厂模式:提供一个建立一系列相关或相互依赖对象的接口,而无须指定它们具体的类。
抽象工厂模式又叫Kit模式,是一种对象建立型模式。
3d

结构图以下:
在这里插入图片描述code

抽象工厂模式包含四个角色:对象

  • AbstractFactory(抽象工厂):声明了一组用于建立一族产品的方法,每个方法对应一种产品
  • ConcreteFactory(具体工厂):实现了在抽象工厂中声明的建立产品的方法,生成一组具体产品,这些产品构成了一个产品族,每个产品都位于某个产品的等级结构中
  • AbstractProduct(抽象产品):为每种产品声明接口,在抽象产品中声明了产品所具备的业务方法
  • ConcreteProduct(具体产品):定义具体工厂生产的具体对象,实如今抽象层产品接口中声明的业务方法

3 实例

界面皮肤库设计:开发一套皮肤库,用户能够经过菜单选择皮肤,不一样的皮肤提供视觉不一样的按钮,文本框等UI元素。blog

这里简单起见假设开发两套皮肤:继承

  • 春季皮肤(SpringSkin)
  • 夏季皮肤(SummerSkin)

每套皮肤具备如下UI元素:接口

  • 按钮(Button)
  • 文本框(TextField)
  • 组合框(ComboBox)

首先是UI元素,包括抽象元素以及具体元素:

interface Button
{
    void display();
}

class SpringButton implements Button
{
    public void display()
    {
        System.out.println("春季皮肤按钮");
    }
}

class SummerButton implements Button
{
    public void display()
    {
        System.out.println("夏季皮肤按钮");
    }
}

interface TextField
{
    void display();
}

class SpringTextField implements TextField
{
    public void display()
    {
        System.out.println("春季皮肤文本框");
    }
}

class SummerTextField implements TextField
{
    public void display()
    {
        System.out.println("夏季皮肤文本框");
    }
}

interface ComboBox
{
    void display();
}

class SpringComboBox implements ComboBox
{
    public void display()
    {
        System.out.println("春季皮肤组合框");
    }
}

class SummerComboBox implements ComboBox
{
    public void display()
    {
        System.out.println("夏季皮肤组合框");
    }
}

接着是工厂类,包括抽象工厂以及具体工厂:

interface SkinFactory
{
    Button createButton();
    TextField createTextField();
    ComboBox createComboBox();
}

class SpringSkinFactory implements SkinFactory
{
    public Button createButton()
    {
        return new SpringButton();
    }

    public TextField createTextField()
    {
        return new SpringTextField();
    }

    public ComboBox createComboBox()
    {
        return new SpringComboBox();
    }
}

class SummerSkinFactory implements SkinFactory
{
    public Button createButton()
    {
        return new SummerButton();
    }

    public TextField createTextField()
    {
        return new SummerTextField();
    }

    public ComboBox createComboBox()
    {
        return new SummerComboBox();
    }
}

测试:

public class Test
{
    public static void main(String[] args) {
        SkinFactory factory = new SpringSkinFactory();
        factory.createButton().display();
        factory.createTextField().display();
        factory.createComboBox().display();

        factory = new SummerSkinFactory();
        factory.createButton().display();
        factory.createTextField().display();
        factory.createComboBox().display();
    }
}

4 有关OCP

虽然使用抽象工厂模式增长新的皮肤界面很是方便,可是若是增长一个UI元素,会修改大量的代码,须要修改抽象工厂以及每个具体工厂类,也就是说,不可以在符合OCP(开放闭合原则)的前提下增长新的组件。
这是抽象工厂模式的最大缺点,尽管增长新的产品族(这里是皮肤)很是方便,可是增长新的产品等级结构(这里是UI元素)很麻烦。抽象工厂模式的这种性质叫作开闭原则的倾斜性。所以设计人员在设计之初须要全面考虑,不然新增产品结构会致使大量的代码修改。

5 主要优势

  • 隔离:抽象工厂模式隔离了具体类的生成,使得客户并不须要知道什么被建立。因为这种隔离更换一个具体工厂类变得很相对容易,全部的具体工厂都实现了在抽象工厂中声明的那些公共接口,所以只需改变具体工厂的实例,就能够在某种程度上改变整个软件系统的行为
  • 同一产品族对象:当一个产品族中的多个对象被设计成一块儿工做时,它可以保证客户端始终只使用同一个产品族中的对象
  • 增长产品族容易:增长新的产品族容易,无须修改已有系统,符合OCP

6 主要缺点

主要缺点是增长新的产品等级结构麻烦,须要对系统进行大量的修改,违背了OCP

7 适用场景

  • 一个系统不当应依赖与产品类实例如何被建立,组合和表达细节,这对于全部类型的工厂模式都是很重要的,用户无须关心对象的建立过程,将对象的建立以及使用解耦
  • 系统中有多于一个的产品族,而每次只使用其中某一产品族
  • 属于同一个产品族的产品将在一块儿使用,这一约束必须在系统的设计中体现出来。同一个产品族中的产品能够是没有任何关系的对象,可是它们都具备一些共同的约束。例如同一皮肤下的按钮以及文本框,按钮与文本框没有直接联系,可是都属于同一皮肤
  • 产品等级结构稳定,设计完成后,不会向系统中增长新的产品等级结构或者删除已有的产品等级结构

8 总结

在这里插入图片描述

相关文章
相关标签/搜索