设计模式学习之工厂模式

55 阅读5分钟

读书笔记之10,15


工厂模式

直接new 时存在的一些问题

思考:我们在前面已经明确了:我们应该面向接口编程,而非面向实现。当我们每次使用new时不就是在针对实现编程吗?

当使用new时,你的确是在实例化一个具体都类。代码绑着具体的类会更加的脆弱,更缺乏弹性。

Duck duck = new WoodDuck();

image.png

针对接口编程,我们可以隔离掉以后系统可能发生的一大堆改变。为什么呢?如果代码是针对接口写的那么通过多态,它可以与任何的新类实现该接口。但是当代吗使用大量的具体类时,就是自找麻烦,因为一旦加入了新的具体的类,就必须改变代码。也就是说你的代码并非对修改关闭

简单工厂模式的实现

引出问题

假设你是饮料店的老板,饮料的订单相关的可能会这样写。

Drink orderDrink(String type){
    Drink drink;
    if("kele"){
        drink = new keleDrink();
    }else if("果汁"){
        drink = new GuoZhiDrink();
    }else{
        drink = null;
    }
    drink.装盒();
    return drink;
    } 
}

但是当增加更多的饮料类型,还有一些饮料可能卖的不好需要去掉时:下面是在书中案例的视图:

image.png

解决问题

从上面的代码我们可以发现在order 订单的方法中当使用具体的类时可能需要频繁修改,这会对原来的代码造成影响,可能在多次修改过程中不小心改变了原先的不需要修改的部分,我们可以考虑使用我们之前学过的一个原则:封装变化,将变化的部分与固定的代码分离出来 不难发现在上面的代码中变化的部分就是创建对象的部分。 我们可以将创建对象的部分分离出来放到一个新的对象中该对象只负责对象的创建,我们称这个新的对象为:工厂

public class SimpleDrinkFactory{
    public Drink createDrink(String type){
        Drink drink = null;
        if("kele"){
            drink = new keleDrink();
        }else if("果汁"){
            drink = new GuoZhiDrink();
        }else{
            drink = null;
        }
   
    return drink;
    }

问题:这么做好像只是把问题搬到另外一个对象中,这样做有什么用???

他可以为更多客户服务,在当前只有order方法,但是可能还会有别的客户。总而言之该创建对象的工厂可以有许多的客户。 把创建产品的类封装进一个单独的类,当以后需求改动时我们只修改这个类就够了。

问题:把工厂定义成一个静态的方法。这有什么差别?

把工厂方法定义为静态的方法是常见的技巧。被称为静态工厂。为何使用静态工厂:是因为不需要创建对象就可以直接实例化对象。但请记住这种方法也有缺点:不能通过继承来改变创建方法的行为。(what??)😂

image.png

思考: 我们知道对象组合可以在运行时动态地改变行为,因为我们可以更换不同的实现。在上面的pizzaStore例子中应该>如何做到这一点?有哪些工厂实现能够被我们自由地更换?

**简单工厂其实不是一个设计模式,反而像是一种编程习惯。

image.png

提示:在设计模式中的所谓的“实现一个接口”并不一定是表示一个要写一个类用他来通过implements关键字来实现某个java的接口。“实现接口”泛指实现某个超类(可以是类或者接口)

工厂方法的模式

image.png

加盟披萨店

当需要制作不同区域的pizza时我们的解决方法之一就是: 利用SimplePizzaFactory 写出需要的几种不同的工厂。

添加自己的特色

加盟店确实是采用了我们之前的工厂创建pizza,但是其他部分采用自创的流程:烘烤的做法差异,不要切片,使用其他厂商的盒子

在想想这个问题,你真的希望能够建立一个框架,把加盟店和创建pizza捆绑在一起的同时又保持一定的弹性!!!

我们在稍早的SimplePizzaFactory,将制作pizza的代码绑在PizzaStore但是这么做没有弹性。

解决:

有个做法可以解决上述的问题让pizza的制作活动局限于PizzaStore类,而同时又能让这些加盟店依然可以自由地制作区域的风味。

将createPizza()方法放回到PizzaStore并将方法声明为抽象,然后为每个区域风格创建PizzaStore子类。

允许子类做决定

image.png

image.png

上图中的orderPizza()方法对pizza对象做了很多事情,但是由于Pizza对象是抽象的,所以orderPizza()并不知道道哪些实际的具体类参与进来了。换句话说,这就是解耦(decouple)

image.png

image.png

声明工厂方法

原本是一个对象负责所有的具体类的实例化,现在通过对pizzaStore做一些小转变,编程由有一群子类负责实例化:

image.png

如何订购?

image.png

image.png

image.png

认识工厂方法的模式

image.png

定义工厂方法的模式

工厂方法模式:定义了一个创建对象的接口,但是由子类决定实例化的类是哪一个。工厂方法让类把实例化推迟到子类。

image.png


未完。。。。。。。。。