HeadFirst 设计模式学习笔记4--工厂模式

来源:互联网 发布:js 图片放大缩小 编辑:程序博客网 时间:2024/05/16 17:52

1.我们在前边提到一个原则就是“面向接口而不要面向实现编程”,但是我们一直在使用Duck duck = new MallardDuck()这样的模式,后边的new语句却违反了这个原则。工厂方法就可以解决这个问题,它用来封装对象的创建。

2.这一节我们考虑如下场景:一个披萨店要制作各种各样的披萨,甚至还要开分店。其中涉及到订购披萨的步骤。我们可以把orderPizza中的关于制作pizza的部分单独提取到一个类中。

而制作pizza的类如下:

这样,一个pizza商店在制作pizza时等于有了一个供应商一样的东西专门去制作,而商店不必要去关心这些的细节。这本来是可以再orderPizza中实现的,现在单独形成类时为了可以服务更多的商店(比如同时经营的连锁店)或者不同的吃法(比如送货上门)。这样的实现称为简单工厂模式,也可以使用静态方法来定义者这个工厂方法,当然这样的实现有个缺点就是无法通过继承改变创建方法的行为。注意,简单工厂模式并不等价于工厂模式。

3.现在我们考虑更多加盟店的需求:他们需要他们自己风格的口味,但是加盟店的一些业务流程又必须严格按照总店进行处理。我们重新设计PizzaStore类:

此时,我们开一家芝加哥的分店:

我们然后现在pizza本身的一些事情:

根据总店的规定,我们来自定义一个芝加哥风味的pizza:

OK,All done,我们可以去吃一顿披萨大餐了:

4.工厂方法模式的定义:定义了一个创建对象的接口(abstract createPizza),但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。优点在于将创建对象的代码集中在一个类或者方法中,可以避免代码中的重复,并且方便以后的管理,并且客户在实例化对象时只会依赖于接口而不是具体的类。在代码中使用new创建其他的类就是对其他类的依赖,减少对于具体类的依赖是件好事情,这就引出我们第六个设计原则:要依赖抽象,不要依赖具体类——这有点类似于我们第一个原则,但是这里更强调不能让高层组件依赖低层组件,而且,两者都应该依赖于抽象。在这个例子中,XXXPizza  --> Pizza <—PizzaStore ,而Pizza则是一个抽象类,这就是well designed.思维的方式是逆向思维,在设计系统时,先从底部向上抽象(抽象出Pizza类),然后撇开具体的类,在抽象层面拓展(设计PizzaStore),有几个原则可以帮助我们规范使用这个原则,这些并不是都要做到,只要尽力即可:变量不可以持有具体类的引用(pizza就没有持有任何具体类的引用),不要让类派生自具体类(都是从抽象类派生出来的),不要覆盖基类中已经实现的方法。

5.抽象工厂模式:

我们现在的场景是要在Pizza上采用不同的原料,针对不同的分店,首先我们先定义一个产生原料的工厂,我们有六种原料要供应:

我们根据这一模式构建各地的分工厂:

现在我们就做一个pizza,使用原料工厂提供的原料:

针对这一个基本的方式,我们构建具体的Pizza:

接着,我们要在店面流程上做抽象:

在这个抽象的基础上我们开一家分店:

现在我们试着订购一个Pizza:

抽象工厂模式提供了一个接口,用于创建相关或者依赖的对象家族,而不需要明确指定具体类,每个家族成员都负责创建一个具体的产品。与工厂方法的区别在于:工厂方法使用继承,针对的是类,利用工厂方法创建对象要扩展一个类,并覆盖它的工厂方法(createPizza)——用来创建对象,工厂方法的实质在于通过子类创建对象;抽象工程方法使用的是组合,针对的是一族对象,要使用这个工厂要首先将其实例化,然后将它传入一些针对抽象类型所写的代码中,优点在于可以把一群相关的产品集合起来,具体的工厂都是由工厂方法创建的。

在这个例子中商店的实现是采用的工厂方法,而制作Pizza的原料相关的类是采用的抽象工厂方法

原创粉丝点击