Bootstrap

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

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

从这一专栏开始将学习设计模式,上课学习和自己总结归纳的笔记将总结出来供大家参考。
参考书籍:《设计模式就该这样学》

其他文章:

Java设计模式-UML类图Java设计模式-七大架构设计原则-开闭原则
Java设计模式-七大架构设计原则-依赖倒置原则Java设计模式-七大架构设计原则-单一职责原则
Java设计模式-七大架构设计原则-接口隔离原则Java设计模式-七大架构设计原则-最少知道原则(迪米特法则)
Java设计模式-七大架构设计原则-里氏替换原则和合成复用原则Java设计模式-创建型设计模式-简单工厂模式
Java设计模式-创建型设计模式-工厂方法模式(工厂模式)Java设计模式-创建型设计模式-抽象工厂模式
Java设计模式-创建型设计模式-建造者模式Java设计模式-创建型设计模式-原型模式
Java设计模式-创建型设计模式-单例模式Java设计模式-结构型设计模式-适配器模式
Java设计模式- 结构型设计模式-享元模式Java设计模式- 结构型设计模式-外观模式
Java设计模式- 结构型设计模式-桥接模式Java设计模式-结构型模式设计模式-组合模式
Java设计模式-行为型设计模式-观察者模式

一、创建型设计模式

创建型模式对类的实例化过程进行了抽象,能够将软件模块中对象的创建和对象的使用分离,对客户端代码需要调用对象的时候隐藏了类的实例化的创建细节

其中包括:简单工厂模式(不在GoF23种设计模式中)、工厂方法模式、抽象工厂模式、建造者模式、原型模式、单例模式。

二、抽象工厂模式

1.抽象工厂模式定义

抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂,该超级工厂又称为其他工厂的工厂,在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象

在GoF23种设计模式中属于创建型设计模式

其中包括:简单工厂模式(不在GoF23种设计模式中)、工厂方法模式、抽象工厂模式、建造者模式、原型模式、单例模式。

2.产品等级结构和产品族

在这里插入图片描述

(1) 产品等级结构:产品等级结构即产品的继承结构,如一个抽象类是电视机,其子类有海尔电视机、海信电视机、TCL 电视机,则抽象电视机与具体品牌的电视机之间构成了一个产品等级结构,抽象电视机是父类,而具体品牌的电视机是其子类。

(2) 产品族:在抽象工厂模式中,产品族是指由同一个工厂生产的,位于不同产品等级结构中的一组产品,如海尔电器工厂生产的海尔电视机、海尔电冰箱,海尔电视机位于电视机产品等级结构中,海尔电冰箱位于电冰箱产品等级结构中,海尔电视机、海尔电冰箱构成了一个产品族。

3.抽象工厂模式的角色

同工厂方法模式一样,抽象工厂模式也是这四个角色

抽象工厂(Abstract Factory):提供了创建产品的接口,它包含多个创建产品的方法 newProduct(),可以创建多个不同等级的产品。
具体工厂(Concrete Factory):主要是实现抽象工厂中的多个抽象方法,完成具体产品的创建。
抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能,抽象工厂模式有多个抽象产品。
具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间是多对一的关系。

4.抽象工厂模式的特点

优点:

抽象工厂模式除了具有工厂方法模式的优点外,最主要的优点就是可以在类的内部对产品族进行约束。所谓的产品族,一般或多或少的都存在一定的关联,抽象工厂模式就可以在类内部对产品族的关联关系进行定义和描述,而不必专门引入一个新的类来进行管理。

缺点:

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

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

5.抽象工厂模式的类图

在这里插入图片描述

6.抽象工厂模式的代码实现

6.1案例

在这里插入图片描述

抽象产品:按钮、文本框、组合框

具体产品:浅绿色的按钮、绿色边框的文本框、绿色边框的组合框、浅蓝色的按钮、蓝色边框的文本框、蓝色边框的组合框

抽象工厂:皮肤工厂

具体工厂:Spring风格工厂、Summer风格工厂

类图如下:

在这里插入图片描述

6.2具体代码实现

1.抽象产品(Button)接口和具体产品类(SpringButton、SummerButton)

public interface Button {
    void display();
}
public class SpringButton implements Button {
    @Override
    public void display() {
        System.out.println("浅绿色的按钮");
    }
}
public class SummerButton implements Button {
    @Override
    public void display() {
        System.out.println("浅蓝色的按钮");
    }
}

2.抽象产品(TextField)接口和具体产品类(SpringTextField、SummerTextField)

public interface TextField {
    void display();
}
public class SpringTextField implements TextField{
    public void display(){
        System.out.println("显示绿色边框文本框");
    }
}
public class SummerTextField implements TextField{
    public void display(){
        System.out.println("显示蓝色边框文本框");
    }
}

3.抽象产品(ComboBox)接口和具体产品类(SpringComboBox、SummerComboBox)

public interface ComboBox{
  void display();
}		
public class SpringComboBox implements ComboBox{
    public void display(){
        System.out.println("显示绿色边框组合框");
    }
}
public class SummerComboBox implements  ComboBox {
    @Override
    public void display() {
        System.out.println("显示蓝色边框组合框");
    }
}

4.抽象工厂(SkinFactory)接口和具体工厂类(SpringSkinFactory、SummerSkinFactory)

public interface SkinFactory {
    Button createButton();
    TextField createTextField();
    ComboBox createComboBox();
}
public class SpringSkinFactory implements SkinFactory{
    public Button createButton(){
        return new SpringButton();
    }
    public TextField createTextField(){
        return new SpringTextField();
    }
    public ComboBox createComboBox(){
        return new SpringComboBox();
    }
}
public class SummerSkinFactory implements SkinFactory{
    public Button createButton(){
        return new SummerButton();
    }
    public TextField createTextField(){
        return new SummerTextField();
    }
    public ComboBox createComboBox(){
        return new SummerComboBox();
    }
}

5.配置文件SkinProperties.properties,在配置文件中存储了具体工厂类的类名。

FactoryClassName=com.abstractfactory.skinfactory.SpringSkinFactory

6.ConfigUtils(读取配置文件工具类)

public class ConfigUtils {
    /**
     * 从properties文件中创建Bean对象
     * @param fileName properties文件名
     * @param key 包含的Bean对象的类名的配置项
     * @return Bean实例
     */
    public static <T>T getBeanFromProp(String fileName,String key) {
        try {
            Properties pros = new Properties();
            InputStream is =ConfigUtils.class.getClassLoader().getResourceAsStream(fileName);
            //加载配置文件
            pros.load(is);
            //通过反射创建Bean实例
            Class clazz = Class.forName(pros.getProperty(key));
            T bean=(T)clazz.newInstance();
            return bean;

        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

}

7.Client(客户端测试类)

public class Client {
    public static void main(String[] args) {
        SkinFactory skinFactory = ConfigUtils.getBeanFromProp("SkinProperties.properties", "FactoryClassName");
        Button button = skinFactory.createButton();
        ComboBox comboBox = skinFactory.createComboBox();
        TextField textField = skinFactory.createTextField();
        button.display();
        comboBox.display();
        textField.display();
    }
}

8.测试结果

在这里插入图片描述

;