代码改变世界

简单工厂与抽象工厂(基于抽象方法的多态)

2013-10-10 23:14  95胖子  阅读(280)  评论(0)    收藏  举报

场景1

我们在餐馆吃饭,需要一双筷子夹菜。

按照此思路,我们需要建一个筷子类,还需要在筷子类中创建一个夹菜的方法。然后在主程序中实例化筷子类并调用夹菜方法。

场景2

筷子有多种材质,比如说木筷子和竹筷子等。

按照此思路,我们需要创建木筷子类和竹筷子类。分别在主程序中实例化竹筷子类和木筷子类,调用夹菜方法。

场景2_续

我需要筷子夹菜

 

现在有两种材质的筷子了(竹筷子和木筷子),但是我到底该用哪段代码呢???

问题思路:其实我就需要一双筷子夹菜,我并不关心它的材质,只要能夹菜就行。实际上这问题是由两种不同材质的筷子带来的。但是他们的实行的是一种统一的功能:夹菜。如果                  说有一个统一的筷子类就没这么麻烦了。

解题思路:修改筷子类,将其抽象。写一个夹菜的抽象方法,由特定筷子实现夹菜的功能。

修改竹筷子类和木筷子类。(筷子类做为竹筷子类和木筷子类的基类,在竹筷子和木筷子中重写(override)夹菜方法)

 

对象引用统一为抽象基类
到现在为止,“=”赋值运算符左边的问题已经解决。
但是右边呢? 实例化一双筷子 ? 创建筷子的实例?生产筷子?
问题思路: 生产筷子?那是筷子工厂的事,为神马要我们这些使用筷子的人负责呢? 
解题思路:建个筷子工厂。
  
你到底要哪种筷子?new 哪一个?调哪个构造函数?
方法一: 为生产筷子方法增加参数 (string 材质)
调用工厂的静态方法
这种方法有个问题就是:当要换种筷子时,仍然要修改代码,重新编译.
方法二: 将此参数放入配置文件则彻底解决 “=”赋值运算符 右边的问题(App.config)

添加引用system.confiuration

修改加工筷子方法

 在主程序中调用

简单工厂的设计模式原理结构

 

简单工厂—总结
 
•Simple Factory Pattern
•属于创建型模式,又叫做静态工厂方法模式(StaticFactory Method)
•不属于23个GoF模式
•本质:封装对象创建的实现
•多个不同的具体产品类共享同一个抽象的产品基类,工厂的静态方法负责提供抽象产品基类类型的某种具体产品实例,方法内部根据客户端制定的条件来决定返回的究竟是哪种具体产品类型的实例。
 
场景3
筷子工厂的老板生意做大了,现在不但要生产筷子,还要生产饭勺。
问题思路:按照之前的做法,一种抽象的饭勺类,两种具体材质的饭勺类
场景3_续
现在看来需要两家工厂了,一家筷子工厂,一家饭勺工厂
解题思路: 现在可以往两个方向建工厂了:一个是按照用途【夹菜】、【盛饭】,l另一个就是按照【材质】。 
产品系列向两个维度发展,需要规划一下。
按餐具的材质分开生产 : 降低生产成本,易于管理...( 竹制餐具加工厂 和 木制餐具加工厂
到这里问题产生了, 有时要用竹制餐具,有时要用木制餐具, 换用不同材质的餐具时,发生了惨剧~(?)
 
又回到了原来的问题:我们使用餐具夹菜盛饭的人,不关心筷子饭勺是竹质还是木质,更不关心餐具由哪家工厂生产,何必叫我们声明和实例化特定材质的餐具加工厂 呢?
解题思路: 产品(筷子、饭勺)可以抽象,工厂难道就不可以么? 把两种餐具加工厂抽象为统一的 餐具加工厂。 期望:你能从它那里 得到 由它生产而你想要的 筷子饭勺 等   餐具,从而 夹菜盛饭,无需关心它们是竹制还是木制,也不用知道来自哪家工厂。
 
增加餐具加工厂类
 修改竹制餐具加工厂 和 木制餐具加工厂类
 
使用抽象工厂提供的产品。
还需要解决 "="赋值运算符右边new 调用子类构造函数的问题。
解题思路: 由抽象的餐具加工厂类本身提供静态方法,它负责实例化一个特定材质的餐具加工厂子类对象。
 
至此工厂的使用者不再需要调用子类构造函数。
 
 
 最后: 
•程序运行时由配置文件使用的餐具是用木制的还是用竹制的。
•当变更配置时,代码不需更改,也不需重新编
 
抽象工厂—总结
 
•Abstract Factory Pattern
•属于23个GoF模式
•在简单工厂的基础上进化:
–多个不同的具体工厂类生产不同系列的产品,它们共享同一个抽象的工厂基类,抽象工厂的静态方法负责提供抽象工厂基类类型的某种具体工厂的实例,方法内部根据客户端制定的条件决定返回的究竟是哪种具体工厂类型的实例