设计模式之->工厂模式

1.定义:工厂模式是 我们最常用的实例化对象模式了,是用工厂方法代替new操作的一种模式。著名的jive论坛,就大量使用了工厂模式,工厂模式在java程序系统可以说是随处可见。因为工厂模式就相当于创建实例化对象的new,我们经常要根据累class生成实力对象,如 A a = new A() 工厂模式也是用来创建实例对象的,所以在new时候要多大考虑是否可以用工厂模式实现,虽然这样做会多做一些工作,但是会给你的系统带来更大的可扩展性和尽量少的修改量

下面是我阅读 head first 设计模式学习归纳总结的关于工厂模式的由浅入深的分析,如有问题,请多多指教~~~

假设 我开设一家披萨店 ,那么关于披萨代码似乎可以这样实现

pizza orderPizza(){
        pizza pizza = new Pizza();
        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();
        pizza.pizza();

}       //为了让系统有弹性,我们很希望这是一个抽象类或者接口。但如果这样,这些类或者接口就无法直接实例化    

但是你需要更多的披萨类型。。。。。。 你就会如下这样做

pizza orderPizza(string type){
        pizza pizza;
        if(type.equals("cheese")){
            pizza = new cheesePizza();
        }else if(type.equals("greek")){
           pizza  = new greekPizza();

        }

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

}       //根据pizza类型,我们去实例化具体的披萨类,然后将其赋值给pizza实例变量。请注意,这里的任何披萨都必须实现pizza接口    

上面代码解决了增加不同类型的披萨 ,但是压力来源于日益增加的披萨类型 ,由简单几种变成十几种 二十 几种、三十几种 、成千上万种时候呢。。。。又同时有一些销量不好的披萨 需要去除时候 我们怎么办?
我们每次 在 orderPizza中 去除 下架的pizza 增加新增的pizza 很明显 如果实例化“某些”具体类,将使orderpizza 出现问题,而且我们也无法让orderPizza() 对修改关闭;但是,现在我们已经知道那些会改变,那些不会改变,该是使用封装的时候了。

封装创建对象的代码 。。。。

 orderpizza 里的newif(type.equals("cheese")){
            pizza = new cheesePizza();
        }else if(type.equals("greek")){
           pizza  = new greekPizza();

        }

单独抽象出去。。。。 放到另一个对象里去,这个对象只管如何创建披萨,如果任何对象想创建披萨直接找它就对了

我们称这个新的对象就是“工厂” factory

工厂:处理创建对象的细节,一旦有了披萨工厂,orderpizza()就变成这个工厂对象的客户了,需要什么披萨 就找工厂去做,自身不需要知道披萨的类型,下面我们建立一个简单的披萨工厂

我们要封装一个工厂类为所有类型的披萨生产披萨

public class simlePizzaFactory{
     public pizza createPizza(string type){
           pizza pizza =null;
    }

    if(type.equals("cheese")){
             pizza = new cheesePizza();

    }else if(.....){
        ......
    }.....

    return pizza ;

} //大家一定看出这样做其实并没有改变什么 只不过是把问题从orderPizza中拿出 依然也是以披萨的类型为参数的。

———————-现在我们重新做一个披萨类pizzaStore——————-

是时候修改我们的客户代码了,我们所要的就是仰仗工厂为我们创建披萨,要这样改变:

pizza orderStore(){
       simplePizzaFactory  factory ;
       public PizzaStroe(simplePizzaFactory factory){
              this.factory = faactory;
        }

        pubic Pizza orderPizza(string type){
              pizza pizza;
              pizza = factory.createPizza(type);
              pizza.prepare();
              pizza.bake();
              pizza.cut();
              pizza.box();
              pizza.pizza();
              return pizza;
         }
       //这里是其他的方法
}   //注意这里我们把new 操作换成了工厂的创建披萨的方法函数,这里不再使用具体的实例化      

定义简单的工厂

简单的工厂模式不是一个设计模式,反而比较像是一种编程习惯。但由于经常被使用,所以我们给它一个“head first pattern 荣誉奖“。 有一些开发人员的确是把这个编程习惯当成是工厂模式,当你下次和另一个开发人员之间无话可说的时候,这应当是打破沉默的不错话题。
不要因为简单工厂不是一个”真正的“模式,就忽略了它的用法。让我们来看看新的披萨类图:

Created with Raphaël 2.1.0 pizzastore pizzastore simplePizzaFactory simplePizzaFactory pizzastore:orderPizza() 是工厂的客户 simplePizzaFactory:createPizza()声明为静态的 工厂客户通过simplePizzaFactory获取批准实例
Created with Raphaël 2.1.0 pizza pizza simplePizzaFactory simplePizzaFactory prepare()、bake()、 cut()、 box() 工厂客户通过simplePizzaFactory获取批准实例 cheesepiazza 、veggiepizza、clampizza、pepperonipizza

这是我们具体产品每一个产品必须要实现pizza的接口 ,并设计成一个具体类,这样一来就可以被工厂创建,并返回给客户。

加盟披萨店

我们已经有一个做法。。。。

如果利用simplepizzafactory 写出几种不同的工厂,分别是NYpizzafactory、ChicagoPizzafactory、CaliforniaPizzafactory,那么各地加盟店都有适合的工厂可以使用,这是一种做法

但是我们想要多一些质量控制。。。。。

在推广simplepizzafactory 时,你会发现 加盟店的确是采用你的工厂创建的,但是其他的呢,烘烤的做法有差异、不要切片、使用其它厂商的盒子。。。。。

所以这个时候你希望能够建立一个框架,把加盟店和创建披萨捆绑在一起的时候又保持一定弹性。

给披萨店使用的框架

public abstract class PizzaStore{

     public pizza orderPizza(string type){
            pizza pizza;
            pizza = createPizza(type);
            pizza.prepare();
            pizza.bake();
            pizza.cut();
            pizza.box();
            return pizza;
     }

     abstract pizza createPizza(string type);
     //现在把工厂对象移回这个方法里面,在pizzastore里面工厂方法是抽象的。
}

允许子类做决定

当orderpizza()调用createPizza()时,某个披萨子类奖负责创建披萨。做哪一种披萨呢?当然由具体的披萨店决定。。

优缺点:
优点:克服了简单工厂违背开放-封闭原则的缺点,又保留了封装对象创建过程的优点,降低客户端和工厂的耦合性,所以说“工厂模式”是“简单工厂模式”的进一步抽象和推广。

缺点:每增加一个产品,相应的也要增加一个子工厂,加大了额外的开发量。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值