工厂模式(Factory pattern)

  工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

  在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。

  一、原始写法

  在使用工厂模式之前,我们一般这样写

  第一步、先创建一个超类

package lcl.mm.pattern.factory.simpledemo;

import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;

@Slf4j
public class Pizza {
    public String name;
    public String dough;
    public String sauce;
    public ArrayList topping = new ArrayList();

    public void prepare(){
        log.info("准备pizza");
        log.info("揉面");
        log.info("加酱");
        log.info("添加调料");
    }

    public void bake(){
        log.info("烤pizza");
    }

    public void cut(){
        log.info("切pizza");
    }

    public void box(){
        log.info("打包pizza");
    }


}

  第二步、该超类下可能存在多个子类

package lcl.mm.pattern.factory.simpledemo;

public class BjPizza extends Pizza {
    public BjPizza(){
        name = "北京风味的奶酪披萨";
        dough = "北京面团";
        sauce = "北京番茄酱";
        topping.add("北京高级奶酪");
    }
}
package lcl.mm.pattern.factory.simpledemo;

public class ShPizza extends Pizza {
    public ShPizza(){
        name = "上海风味的奶酪披萨";
        dough = "上海面团";
        sauce = "上海番茄酱";
        topping.add("上海高级奶酪");
    }
}

  第三步,就是实际的创建对象和使用对象了

package lcl.mm.pattern.factory.simpledemo;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class PizzaStore {
    public Pizza orderPizz(String type){
        Pizza pizza = null;
        if(type.equals("BJ")){
            pizza = new BjPizza();
        }else if(type.equals("SH")){
            pizza = new ShPizza();
        }

        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();
        return pizza;
    }
}

   可以看到,直接在代码种new了对象,然后进行相关操作。那么这里就存在一个问题,就是每当我们新增一个新的对象时,都要新增 if 分支去创建新的对象,那么就不满足对 设计模式的 【开闭原则】,那么怎么处理呢?那么就可以使用简单设计模式。

 二、简单工厂模式

  简单设计模式就是把创建对象单独抽取成一个类,将类的创建与类的使用分离。

  实际上简单工厂模式并不是一个设计模式,而更像一个编程习惯,但由于经常被使用,因此也经常被纳入设计模式里。

  那么简单工厂模式第一步就是将创建类的代码单独抽取成一个类

package lcl.mm.pattern.factory.simpledemo;

public class SimplePizzaFactory {
    public Pizza creatPizza(String type){
        Pizza pizza = null;
        if(type.equals("BJ")){
            pizza = new BjPizza();
        }else if(type.equals("SH")){
            pizza = new ShPizza();
        }
        return pizza;
    }
}

  第二步便是先调用简单工厂类创建对象,然后在对对象进行操作。

package lcl.mm.pattern.factory.simpledemo;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class PizzaStore {

    private SimplePizzaFactory factory;

    public PizzaStore(SimplePizzaFactory factory){
        this.factory = factory;
    }

    public Pizza orderPizza(String type){
        Pizza pizza = factory.creatPizza("BJ");
        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();
        log.info("pizza return:【{}】", JSON.toJSONString(pizza));
        return pizza;
    }

}

  但是上述还存在一个问题,就是对对象的使用被写死了,不能灵活调整,那么该如何处理呢?这里可以使用抽象工厂模式来处理

三、抽象工厂模式

  第一步、先创建超类和对应子类

package lcl.mm.pattern.factory.demo;

import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;

@Slf4j
public abstract class Pizza {
    public String name;
    public String dough;
    public String sauce;
    public ArrayList topping = new ArrayList();

    public void prepare(){
        log.info("准备pizza");
        log.info("揉面");
        log.info("加酱");
        log.info("添加调料");
    }

    public void bake(){
        log.info("烤pizza");
    }

    public void cut(){
        log.info("切pizza");
    }

    public void box(){
        log.info("打包pizza");
    }

    public String getName(){
        return name;
    }

}
package lcl.mm.pattern.factory.demo;

public class ShStyleCheesePizza extends Pizza {
    public ShStyleCheesePizza(){
        name = "上海风味的奶酪披萨";
        dough = "上海面团";
        sauce = "上海番茄酱";
        topping.add("上海高级奶酪");
    }
}
package lcl.mm.pattern.factory.demo;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class BjStyleCheesePizza extends Pizza {
    public BjStyleCheesePizza(){
        name = "北京风味的奶酪披萨";
        dough = "北京面团";
        sauce = "北京番茄酱";
        topping.add("北京高级奶酪");
    }

    public void cut(){
        log.info("将pizza切成正方形");
    }
}

  第二部、创建使用者

  在这一步中,超类有一个抽象的创建对象方法,这样超类就不需要关心创建的具体是哪个对象

package lcl.mm.pattern.factory.demo;

public abstract class PizzaStore {

    public Pizza orderPizza(String type){
        Pizza pizza = creatPizza(type);
        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();
        return pizza;
    }

    public abstract Pizza creatPizza(String type);

}
package lcl.mm.pattern.factory.demo;

public class ShPizzaStore extends PizzaStore {
    @Override
    public Pizza creatPizza(String type) {
        if(type.equals("cheese")){
            return new ShStyleCheesePizza();
        }else {
            return null;
        }
    }
}
package lcl.mm.pattern.factory.demo;

public class BjPizzaStore extends PizzaStore {
    @Override
    public Pizza creatPizza(String type) {
        if(type.equals("cheese")){
            return new BjStyleCheesePizza();
        }else {
            return null;
        }
    }
}

  

原文地址:https://www.cnblogs.com/liconglong/p/13581721.html