这一章,看得比较纠结,以前以为自己看懂了,回顾一下,组织语言想写博客的时候,发现还是没弄清楚。遂又上网查资料,发现一个比较好的网站: http://www.jdon.com/designpatterns/,就是广告多了点,说的还是很明白的。但我发现该网站上所说的工厂模式,似乎与Head First上讲述的模式有些出入,或者是侧重点不同?于是又在wiki上查找,再通过研究Head First的Java代码,终于发现,JDon上的说法确实是对的,即“这两个模式区别在于需要创建对象的复杂程度上”。不过简单工厂,似乎并不是一个模式(Head First,wiki都没有将简单工厂列为模式)下面我来详细说明。
首先,工厂模式是一种针对对象创建的模式,只是提供了一种有弹性的对象创建方案。
工厂方法:定义了一个创建对象的接口,但由子类决定要实例化的类是哪个。工厂方法让类把实例化推迟到子类。
抽象工厂:提供一个接口,用于创建相关或依赖对象的家族,而无需明确指定具体类。
说实话,这两个说明似乎没什么区别,只是工厂方法强调实例化由子类实现,抽象工厂强调它是用于创建对象家族的。
也就是说,工厂方法强调的是,我们需要将对象的创建独立出来,并抽象出一个接口,然后在子类中完成创建;
而抽象工厂则更复杂,他强调的是它需要使用这种抽象接口的方式,构建出一整个对象家族。
从他们的说明中,我们便看出来,他们的层次结构是不一样的。抽象工厂比工厂方法更加抽象,具有更深的封装,更重量级,更复杂。而且,抽象工厂中通常包含着工厂方法,也就是说抽象工厂常由工厂方法来实现。
下面来看一副来自wiki的类图:
这幅图是最简单的抽象工厂,只由两个工厂实例来实例化两个产品实例。
其代码如下:
class Button; // Abstract Class class MacButton: public Button {}; class WinButton: public Button {}; // 对应的工厂的抽象接口 class AbstractFactory { public: virtual Button* CreateButton() =0; virtual Border* CreateBorder() =0; }; // 具体实现 Mac 工厂 class MacFactory: public AbstractFactory { public: MacButton* CreateButton() { return new MacButton; } }; // 具体实现 Win 工厂 class WinFactory: public AbstractFactory { public: WinButton* CreateButton() { return new WinButton; } }; // 客户可以根据需要选择 Mac 风格或者 Win 风格來创建 Button AbstractFactory* fac; switch (style) { case MAC: fac = new MacFactory; break; case WIN: fac = new WinFactory; break; } Button* button = fac->CreateButton();
我们再来看看工厂方法:
其代码也简单许多:
/////////////////////////////////////////////////////////// // 工厂方法: class Button; // Abstract Class class MacButton: public Button {}; class WinButton: public Button {}; // 客户可以根据需要选择 Mac 风格或者 Win 风格來创建 Button switch (style) { case MAC: button = new MacButton; break; case WIN: button = new WinButton; break; }
其变化就是去除了抽象工厂中的工厂类。这么一来,增加了代码的耦合度,但也简化了代码。
所以说,工厂方法,实际上就是一个简化的抽象工厂,其思想都是将类的创建独立出来,并延迟到子类来创建。但是在创建方法较复杂的时候(比如按钮需要很多系统资源调用的时候),抽象工厂可以更好的提供一个独立的环境来提供需要的资源。
前两天事情太多太多,忙着考试,忙着课程设计和实验,还忙着团队的一些事情。今天才得以抽出一点空隙来写完这篇博客。
上周六的时候,想上午就写完博客的,但研究了一天的工厂模式,终于还是模模糊糊,不能完全理解。
又经过后面两天断断续续的思考,好歹才明白过来。
OK,感觉挺不值的,研究了一天才弄清楚如何创建一个对象,囧啊。。。我果然还是比较笨的。。。