《Head First-Chapter4》工厂模式

解决对象的创建问题

------工厂模式(简单工厂、工厂方法、抽象工厂)

一、简单工厂模式

1、问题描述

(1)假设你有一个比萨店,根据比萨类型,制造比萨。


(2)新的需求:GreekPizza卖得不好,把它去掉。新增一些流行口味的比萨:ClamPizza、VeggiePizza

此处暴露问题:没有对修改封闭。有新的需求,还要到这里修改。


2、解决办法:封装创建对象的代码(封装变化)



实现如下:


注:这似乎只是把问题搬到了另一个对象中罢了,问题好像还是存在?值得一提的是,SimplePizzaFactory可能很多地方都用到它,当以后有新需求时,只需修改这个类就好了。



3、简单工厂模式

简单工厂其实不是一个设计模式,反而比较像是一种编程习惯。
比萨店类图:


二、工厂方法模式

1、问题描述

加盟比萨店:所有店都有统一的流程,允许各自制作该区域的风味。

2、简单工厂解决:缺乏统一流程。

NYPizzaFactory nyFactory = new NYPizzaFactory();
PizzaStore   nyStore =  PizzaStore("nyFactory");
nyStore.orderPizza("Veggie");

ChicagoPizzaFactory chicagoFactory = new ChicagoPizzaFactory();
PizzaStore   chicagoStore =  PizzaStore("chicagoFactory");
chicagoStore.orderPizza("Veggie");

缺点:各自的店可能采用自己的流程:如不要切片、使用其它盒子等。

3、工厂方法解决

简单工厂是由一个对象负责所有具体类的实例化,现在通过对PizzaStore做一些小转变, 由一群子类负责实例化
(1)比萨店超类框架


(2)子类实现工厂方法


4、认识工厂方法



5、定义工厂方法模式

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



(3)与简单工厂比较:简单工厂把全部的事情,在一个地方都处理完了,然而工厂方法却是创建一个框架,让子类决定如何实现。
(4)封装变化:把创建对象的代码集中在一个对象或方法中,可以避免代码中的重复,并且更方便以后的维护。这也意味着客户在实例化对象时,只会依赖接口,而不是具体类。这样代码更有弹性,可以应对未来扩展。


6、设计原则:依赖倒置

(1)定义:要依赖抽象,不要依赖具体类。
不能让高层组件依赖低层组件,而且,不管高层或低层组件,“两者”都应该依赖抽象
(2)应用


(3)指导方针
a. 变量不可以持有具体类的引用。
    如果使用new,就会持有具体类的引用。你可以改用工厂来避开这样的做法。
b. 不要让类派生自具体类。
    请派生一个抽象(接口或抽象类)
c. 不要覆盖基类中已实现的方法。
    如果覆盖基类已实现的方法,那么你的基类就不是一个真正适合被继承的抽象。基类中已实现的方法,应该由子类共享。
注:灵活运用,尽量达到这个原则,而不是随时都要遵循这个原则。

三、抽象工厂模式

1、问题描述

对于NYCheesePizza和ChicagoPizza,唯一的差别在于使用区域性的原料,没必要整两个类,让原料工厂处理这种区域差异就可以了。


2、解决办法



3、抽象工厂模式:创建一组对象

(1)定义
提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。
(2)类图


4、比较工厂方法与抽象工厂

(1)都是用于创建对象,工厂方法使用继承扩展一个类,并覆盖它的工厂方法。其实整个工厂方法,就是通过子类来创建对象。
而抽象工厂是用组合,把一群相关的产品集合起来。
(2)工厂方法使用继承:把对象的创建委托给子类,子类实现工厂方法来创建对象。
(3)抽象工厂使用对象组合:对象的创建被实现在工厂接口所暴露出来的方法中。是创建一组对象。





猜你喜欢

转载自blog.csdn.net/wwyl1001/article/details/51290948