[设计模式篇]工厂模式和抽象工厂模式

最近在看Head First的Design Pattern,想想去年候捷来学校给我们讲Design Pattern,但当时水平太弱根本听不懂,今年想趁机再好好学一波,候捷反而不来了,哎,人生就是这样,有些机会真的搞不好只有一次了,所以还是要多多珍惜,不然... ... (再水下去估计没人看了,废话少说,这篇就当一个开篇之作吧,虽然已经看了不少了。)

Head First这本书用了一个披萨店的例子,从简单工厂(严格来说这不算一种Gof的设计模式,更像是一种编程习惯),到介绍工厂模式,再介绍到抽象工厂模式,最后予以总结,个人认为这种结合具体事例来说事的学习方法是非常值得推崇的,这里先对这段过程简单描述一下:

1.假设我们开了一个披萨店,我们会卖各种各样的披萨,我们最开始想到的方法可能就是创建一个基本的Pizza父类,然后通过继承产生我们披萨店卖的各种各样的披萨子类,比如CheesePizza,GreekPizza... ...那么我们在决定生产一个披萨(调用orderPizza)时,我们首先想到的方法是把披萨的类型当作一个参数传给orderPizza,然后写一堆的if else,比如

if (type.equals("Cheese")

//新建一个CheesePizza

else if....(我尽量少些代码,因为都比较好理解)

这就是一个最基本的实现,但随着pizza类型的增多,我们改起来的压力也越来越大,需要不停的使用 if else显然不是一种最佳实践,这是我们就引入“工厂”的概念了;

2.所谓“工厂”,就是为处理创建对象的细节建立的,这里我们的Pizza就可以看作是一个工厂,我们知道它生产Pizza(可能Pizza和披萨混用,大家理解就好),对于上面的情况,我们可以创建一个SimplePizzaFactory(也就是“简单披萨工厂”)将我们需要实例化的Pizza对象扔进去,也就是将那一堆if else放到这里来实现,也就是将创建披萨的代码包装进一个类,以后实现改变时,只需要修改这个类即可,ok,这就是简单工厂的思维。。。。有木有太简单了一点,这么简单的想法怎么能算一种高大上的Design Pattern呢?所以它真的不算设计模式的一种,但这种将变化的部分抽取出来的思维个人感觉是很有必要掌握的,然后继续我们的故事;

3.随着你披萨店的发展,现在出现了不同地方的店像要加盟,比如有上海的,有北京的,有深圳的,不同的店制作的披萨不同,假设上海披萨薄,多汁啥的,北京披萨厚,芝士放得多... ...(就知道它们有区别就行了),这个时候为了满足不同地方的需求,我们需要分别为这三个地方创建不同的披萨店(披萨工厂),分别是ShanghaiPizzaStore,BeijingPizzaStore,ShenZhenPizzaStore,对应不同的披萨店生产不同的披萨(具体的实现细节先不管),在具体的调用中,我们先创建一个具体的披萨店,然后通过这个披萨店传入的参数(比如cheese)来实例化一个披萨,这个过程用以下两行代码:

PizzaStror shStore = new ShanghaiPizzaStore();

Pizza pizza = shStore.orderPizza("cheese");

这样就实例化了一个上海披萨店的起司披萨对象,这很简单,但客官您看好了,这里就引入了设计模式的概念了,对于一个工厂方法来说,我们有两个平行的类层级--产品类和创建者类,这里的产品类就是我们的Pizza,创建者类就是我们的PizzaStore,工厂方法模式“定义了一个创建对象的接口,但由子类决定要实例化的类是那一个。工厂方法让类把实例化推迟到了子类(Define an interface for creating a single object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses )”,它帮助我们将产品的“实现”从“使用”中解耦,也就是说,当我们的产品类受到影响时(披萨种类的增加啥的),我们的创建者PizzaStore并不会受到什么影响,它只负责去这个Pizza工厂中取具体的Pizza,这就时工厂方法模式的基本应用了。(更深入的了解可以去查一查“Dependency Inversion Principle”,大名鼎鼎的“依赖倒置原则”,我也理解得不是很深,暂且按下不表);

4.好了,我们的工厂(产品)类有了,创建者也有了,那抽象工厂又是个什么东东呢?我们回到pizza店,考虑这样一种情况,北京的披萨店和上海的披萨店,它们不但生产的披萨种类不同,这些披萨的原料也不同,也就是实例化一个披萨时,我们要根据其地域来对它的面团,酱料啊具体分析,这个时候怎么办呢?我们这是可以通过定义一个原料工厂的接口,然后在各地域的披萨店里实现这个接口,比如有上海披萨原料工厂,北京披萨原料工厂... ...这样当我们知道我们的披萨店之后,就可以实例化一个具体的原料工厂,这样就可以提取原料来制作对应的披萨了!没错,这就是抽象工厂的思想--"提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类";这里的原料就是一个接口,当我们的创建者确定之后,这个对应的接口也就被对应地实现了,这样创建者就可以从这个工厂中去取我们的披萨原料了,通过这样的组合来完成披萨的制作。

。。。。已经快两点了,明早还有课,介绍就到这里,其实Head First也差不多在这里结束了这张,具体工厂方法模式和抽象工厂的应用,读者可以去参考更多例子。因为我也是初学者,理解肯定不全,我这样记录下来更多是希望大家一起来探索,于反复交流中探取真知,学习不就是这样么?好了,不废话了,欢迎交流,第一篇先到这里。

posted @ 2016-04-19 01:22  Kris_Chan  阅读(300)  评论(0编辑  收藏  举报