美文网首页
工厂模式

工厂模式

作者: 字字经心 | 来源:发表于2022-07-30 16:27 被阅读0次

    工厂模式

    每次用new来实例化对象的时候,都是实例化具体的类,不是面向接口编程,而是实现;代码绑着具体类会导致代码更脆弱,更缺乏弹性,初始化也经常造成耦合的问题。

    假设现在有家披萨Pizza 店,有很多披萨比如pizzaA、pizzaB、pizzaC、pizzaD,产生披萨的类一开始可能会这样写

    Pizza orderPizza(String type){
        // Pizza 抽象类 ABCDE 是实现子类
        Pizza pizza;
        
        if(type.equals("A")){
            pizza = new pizzaA();
        }else if(type.equals("B")){
            pizza = new pizzaB();
        }else if(type.equals("C")){
            pizza = new pizzaC();
        }else if(type.equals("D")){
            pizza = new pizzaD();
        }else if(type.equals("E")){
            pizza = new pizzaE();
        }
        
        // 披萨的其他加工步骤
        pizza.prepare();
        pizza.bake(); //烘烤
        pizza.cut();  //切片
        pizza.box();  //装盒
        return pizza;
    }
    

    这个设计显然违背了 封闭——开放原则,如果pizza 种类增多,或者要去除一些不受欢迎的披萨,就必须修改orderPizza ,而这都是没有对变化封闭的原因。于是我们把创建pizza 那边代码搬移到简单的工厂SimplePizzaFactory

    public class SimplePizzaFactory{
        public Pizza createPizza(String type){
            // Pizza 抽象类 ABCDE 是实现子类
            Pizza pizza = null;
        
            if(type.equals("A")){
                pizza = new pizzaA();
            }else if(type.equals("B")){
                pizza = new pizzaB();
            }else if(type.equals("C")){
                pizza = new pizzaC();
            }else if(type.equals("D")){
                pizza = new pizzaD();
            }else if(type.equals("E")){
                pizza = new pizzaE();
            }
    
            return pizza;
        }
    }
    
    // 修改 orderPizza
    public class PizzaStore{
        SimplePizzaFactory factory;
        
        public PizzaStore(SimplePizzaFactory factory){
            this.factory = factory;
        }
        
        public Pizza orderPizza(String type){
            Pizza pizza;
            pizza = factory.createPizza(type);
            
            // pizza 的其他方法
        }
    }
    

    我们来看一下引入这个简单工厂的类图设计,

    factory1.png

    上面只是一个简单的工厂设计,如果披萨店变得很多了怎么办,createPizza应该生产哪家披萨店的披萨呢?我们可以把pizzaStore 设计成一个抽象类

    public abstract Class PizzaStore {
        public Pizza orderPizza(String type){
            Pizza pizza;
            pizza = createPizza(type);
            
            pizza.prepare();
            pizza.bake();
            // pizza 其他制作方法
            
            return pizza
        }
        
        // createPiza 决定生产那个店的披萨,父类的orderPizza 和子类createPizza 解耦
        abstract Pizza createPizza(String type);
    }
    
    //披萨店A
    pubic class storeAPizzaStore extends PizzaStore{
        Pizza createPizza(String type){
            if(type.equals("A")){
                return new storeApizzaA();
            }else if(type.equals("B")){
                return new storeApizzaB();
            }else if(type.equals("C")){
                return new storeApizzaC();
            }else if(type.equals("D")){
                return new storeApizzaD();
            }
        }
    }
    

    在看看工厂方法的定义

    abstract Product factoryMethod(String type)
    

    工厂方法用来处理对象的创建,并将这样的行为封装在子类中。这样,客户程序中关于超类的代码就和子类对象创建代码解耦了。

    • 工厂方法是抽象,依赖子类实现对象创建
    • 工厂方法必须返回一个产品
    • 工厂方法将客户代码和实际创建具体产品的代码分隔开
    • 参数看情况是否需要

    这样披萨的制作过程代码就是

    pizzaStore storeA = new storeAPizzaStore();
    Pizaa storeAPizzaB = storeA.orderPizza('B');
    
    pizzaStore storeB = new storeBPizzaStore();
    Pizaa storeBPizzaB = storeB.orderPizza('B');
    

    再来看看利用该复杂工厂的设计类图,

    factory2.png

    欢迎大家给我留言,提建议,指出错误,一起讨论学习技术的感受!

    相关文章

      网友评论

          本文标题:工厂模式

          本文链接:https://www.haomeiwen.com/subject/rzrsirtx.html