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

来源:互联网 发布:HTML如何删除某个js 编辑:程序博客网 时间:2024/06/02 13:27

设计原则

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

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

设计模式

工厂模式

工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到了子类。
这句话要加粗:工厂方法让类把实例化推迟到了子类
通常,我们在实例化一个对象的时候,都是直接的进行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类图:
这里写图片描述

0 0
原创粉丝点击