[学习笔记]设计模式[3]-{工厂模式}

本文深入探讨了软件设计中的工厂模式,特别是工厂方法模式的应用,并通过披萨店自动化制作系统的实例,展示了如何利用该模式应对需求变更。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

设计原则

要依赖抽象,不要依赖具体类

这条原则有一个正式的名字:“依赖倒置原则”。这个原则的含义是:不要让高层的组件去依赖低层的组件,而且,这些组件,都应该是依赖于某一个抽象。

设计模式

工厂模式

工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到了子类。
这句话要加粗:工厂方法让类把实例化推迟到了子类
通常,我们在实例化一个对象的时候,都是直接的进行new操作,但是这样会带来这样的问题,如果我们需要根据需要(输入)的不同来新建不同的子类对象,就会产生下面的代码:

myClass mc = null;
if(type.equals("classA")){
    myClass = new ClassA();
}else if(type.equals("classB")){
    myClass = new ClassB();
}else if(type.equals("classC")){
    myClass = new ClassC();
}
//对myClass的其他操作

中间if判断语句很容易产生需求的变化,而这时如果要进行改动就需要对这段代码进行修改,还记得之前的一个设计原则嘛:找出程序中会变化的方面,然后将其和固定不变的方面相分离。
我们还是拿书上的例子来:
披萨店需要做一个自动化披萨机,首先对于每种披萨都有不同的制作流程,披萨制作出来后,需要对披萨进行烘烤、切片、装盒。
下面是基本的代码:

Pizza orderPizza(String type){
    Pizza pizza = null;
    if(type.equals("cheese")){
        pizza = new CheesePizza();
    }else if(type.equals("greek")){
        pizza = new GreekPizza();
    }

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

正如上面所说,根据type去new不同的Pizza这部分很容易发生改变,因为pizza的类型是会增加的,而且销量不好的pizza可能会直接从菜单中撤掉!
那么我们可以把这个方法独立到另外的类中,这样如果需要对pizza的种类进行变化就不需要对orderPizza所在的类进行修改了。
我们可以这样做:

public class SimplePizzaFactory{
    public static Pizza createPizza(String type){
        Pizza pizza = null;
        if(type.equals("cheese")){
            pizza = new CheesePizza();
        }else if(type.equals("greek")){
            pizza = new GreekPizza();
        }
        return pizza;
    }
}

有了这个造pizza的”工厂”,我们就可以对orderPizza进行下面的修改了:

public class PizzaStore{
    SimplePizzaFactory factory;

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

    public Pizza orderPizza(String type){
        Pizza pizza = factory.createPizza(type);
        pizza.bake();
        pizza.cut();
        pizza.box();
    }
}

请注意:这种编程方法(也叫简单工厂)其实并不是一种设计模式,而是一种编程习惯。还记得工厂模式的定义嘛:工厂方法让类把实例化推迟到了子类
下面这个例子才是真正的工厂模式的:
现在披萨店有了各种加盟店。对不同的加盟店有不同的披萨菜单,这时候我们就需要更多的类加入这个系统。
下面是披萨店的工厂方法:

public abstract class PizzaStore{
    public Pizza orderPizza(String type){
        Pizza pizza = createPizza(type);
        pizza.bake();
        pizza.cut();
        pizza.box();
    }

    protected absract Pizza createPizza(String type);
}

上面这个类就是作为不变的部分,是所有披萨加盟店必须继承的类。
下面分别是纽约店和芝加哥店的orderPizza方法:

public class NYPizzaStore extends PizzaStore{
    Pizza createPizza(String type){
        Pizza pizza = null;
        if(type.equals("cheese")){
            pizza = new CheesePizza();
        }//其他种类的Pizza
        return pizza;
    }
}
public class ChicagoPizzaStore extends PizzaStore{
    Pizza createPizza(String type){
        Pizza pizza = null;
        if(type.equals("greek")){
            pizza = new GreekPizza();
        }//其他种类的Pizza
        return pizza;
    }
}

看一下这个模式是怎么工作的:
如果你需要在纽约店定一个芝士披萨:
首先你需要有一个店:PizzaStore nyPizzaStore = new NYPizzaStore();
然后下芝士披萨的订单:nyPizzaStore.orderPizza(“cheese”);
这时候,系统内部会调用createPizza方法: Pizza pizza = createPizza(“cheese”);
再经过pizza.bake();pizza.cut();pizza.box();处理后,你的披萨就出炉啦!
当然,我们还需要披萨这个类。再次就不赘述。
下面是这个例子的UML类图:
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值