zoukankan      html  css  js  c++  java
  • 工厂模式(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;
            }
        }
    }

      

  • 相关阅读:
    html5 自定义属性data-*
    企业微信接口授权
    js对象---字符串
    谈谈html5新增的元素及其他功能
    模拟缓存
    jdbc数据库连接
    面向对象的理解
    最简单的Spring+SpringMVC+Mybatis的整合
    EF报错 附加类型model失败
    c# Web服务远程“调用”调试
  • 原文地址:https://www.cnblogs.com/liconglong/p/13581721.html
Copyright © 2011-2022 走看看