Java设计模式(二)--工厂模式

96 阅读3分钟

简介

在平常开发中初始化一个实例对象的时候,如果这个实例对象初始化的时候需要一系列的流程来进行初始化,此时就造成了代码很臃肿的感觉,可以使用工厂模式来将实例对象初始化的具体流程进行封装,只需要关注所需要创建的实例对象,而不需要去关注实例对象初始化的具体流程。

工厂模式类别

1. 简单工厂模式

2. 工厂方法模式

3. 抽象工厂模式

简单工厂模式

抽象产品

public interface Calculate {

   String getResult();

}

具体产品

public class CalculateAddImpl implements Calculate {

    public String getResult() {
        return "加法";
    }

}

public class CalculateSubImpl implements Calculate {

    public String getResult() {
        return "减法";
    }

}

具体工厂

public class ConcreteFactory {

    public Calculate createCalculate(String type) {
        Calculate calculate = null;
        if("add".equals(type)){
            calculate =  new CalculateAddImpl();
        }else if("sub".equals(type)){
            calculate =  new CalculateSubImpl();
        }
        return calculate;
    }

}

测试

public class SimpleFactoryDemo {

    @Test
    public void Factory() {
        ConcreteFactory factory = new ConcreteFactory();
        Calculate calculate = factory.createCalculate("add");
        System.out.println(calculate.getResult());
    }

}
  • 抽象产品:定义了产品的规范,描述了产品的主要特性和功能。

  • 具体产品:实现或继承抽象产品的子类。

  • 具体工厂:提供了创建具体产品的方法,调用者可以通过该方法来获取产品。

从上面的工厂代码能看出来是通过传递的类型来判断创建指定的实例对象,如果说工厂方法中的判断类型被修改了,此时测试代码中所传递的类型也要更改,并且此时添加了一个乘法和除法的类,工厂中的代码是不是也要进行修改呢?如果进行修改的话就违背了开闭原则,我们可以使用工厂方法模式。

工厂方法模式

具体工厂

public class ConcreteFactory {

    public <T> T createCalculate(Class<T> clazz) {
        Calculate calculate = null;
        try {
            calculate = (Calculate) Class.forName(clazz.getName()).newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return (T) calculate;
    }

}

测试

public class FactoryMethodDemo {

    @Test
    public void Factory() {
        ConcreteFactory factory = new ConcreteFactory();
        CalculateAddImpl calculate = factory.createCalculate(CalculateAddImpl.class);
        System.out.println(calculate.getResult());
    }

}

工厂方法模式中的抽象产品和具体产品与简单工厂中的是相同的,只是具体工厂以及测试代码有区别,具体工厂中是根据Class来创建实例的,只需要将想创建的实例对象的Class传递到具体工厂中去,这样的好处就是如果添加了新的产品类的话,就不用去修改具体工厂的代码,符合开闭原则。

抽象工厂模式

抽象产品A

public interface Button {

    void print();

}

具体产品A

public class WinButton implements Button {

    public void print() {
        System.out.println("WinButton");
    }

}

public class MacButton implements Button {

    public void print() {
        System.out.println("MacButton");
    }

}

抽象产品B

public interface CheckBox {

    void print();

}

具体产品B

public class WinCheckBox implements CheckBox {

    public void print() {
        System.out.println("WinCheckBox");
    }

}

public class MacCheckBox implements CheckBox {

    public void print() {
        System.out.println("MacCheckBox");
    }

}

抽象工厂

public interface Factory {

    Button createButton();

    CheckBox createCheckbox();

}

具体工厂

public class WinFactory implements Factory {

    public Button createButton() {
        return new WinButton();
    }

    public CheckBox createCheckbox() {
        return new WinCheckBox();
    }

}

public class MacFactory implements Factory {

    public Button createButton() {
        return new MacButton();
    }

    public CheckBox createCheckbox() {
        return new MacCheckBox();
    }

}

通过具体工厂来创建一系列相关的产品。

public class Application{

    private Button button;
    private CheckBox checkBox;

    public Application(Factory factory){
        button = factory.createButton();
        checkBox = factory.createCheckbox();
    }

    public void print(){
        button.print();
        checkBox.print();
    }
}

在创建Application的时候传递所需要创建的一系列相关的类型工厂即可,并不需要过多的去关注工厂中一系列产品是如何去创建的,抽象工厂模式与其它两个工厂模式不同的地方就在于一个是创建单个产品的模式,一个是创建一系列相关产品的模式。

总结

工厂模式主要是封装了创建产品的代码,而我们就不需要过多的去关注这个产品是如何进行创建的,我们只需要去关注我们需要哪些产品。