简单工厂模式与反射机制(原创)
简单工厂模式的作用是为了把对象的建立和使用分隔开。
具体描述如下:
简单工厂模式的代码可以分为三块:
1. 第一块是在后台工作的一组类的定义,用于向调用者(客户端)提供服务。
2. 第二块是简单工厂类,用于创建第一块中提到的类的对象。
3. 第三块是客户端,客户端通过第二块中提到的简单工厂类来创建第一块中提到的类的对象,然后在使用这些类的对象来干活。
把代码分开是为了解耦合,最终是为了可扩展。
什么是可扩展呢?
简单地说,当我需要一个新的类,我首先需要在第一块里加上这个一个类的定义(具体操作是添加一个文件,里面包含我要定义的新类)。
然后,我需要在第二块中增加这个类的创建过程。
随后,我就可以在客户端消费这个类了。
我们来看看改动有多大?
首先,第一块里的改动,增加一个新类。这基本上是不可避免的,还好,只是增加一个文件,不需要改原有的文件。符合“开发-封闭”原则。
其次,改类的创建过程,看看,这就不可避免地要改简单工厂类了,很痛苦,在swith下的诸多的case里,再加一个case吧,然后,保存退出。
最后,客户端。客户端基本是不用改动的,如果第一块里的类都符合统一接口的话。
于是,结论:简单工厂类的缺点在于第二块的改动。
如果第二块部分可以不改就好了。有时候,的确可以不改的。这就是反射的功劳。
当客户端需要把需要生成的类的类名告诉简单工厂类的时候,简单工厂类如果可以通过反射机制,直接获取到需要创建的类名。然后生成相应的对象返回,就OK了。
这就避免了switch/case的生成类的模式。
用Python举个简单的例子,在例子里并没有涉及类和对象,不过万物皆对象,函数编程也可以采用简单工厂模式。文件结构如下图:
|-- printClient.py -----第三块
|-- printFactory.py -----第二块
`-- printFun
|-- __init__.py
`-- printMode.py ----第一块
文件内容(__init__.py是空文件):
1 '''
2 printClient.py
3
4 Created on 2010-12-29
5
6 @author: wenxianw
7 '''
8
9 from printFactory import createPrinter
10
11 if __name__ == '__main__':
12 printer = createPrinter("text")
13 printer()
14 printer = createPrinter("xxx")
15 printer()
16
17
18
19
20 '''
21 printFactory.py
22
23 Created on 2010-12-29
24
25 @author: wenxianw
26 '''
27
28 from printFun import printMode
29
30 def createPrinter(mode = "text"):
31 def defFun():
32 print "No such mode: %s!" % mode
33
34 fun = getattr(printMode, "print_%s" % mode, "")
35 if fun != "":
36 return fun
37 else:
38 return defFun
39
40
41 '''
42 printMode.py
43
44 Created on 2010-12-29
45
46 @author: wenxianw
47 '''
48
49 def print_text():
50 print "print in text mode!"
51
52 def print_pdf():
53 print "print in pdf mode!"
54
55 def print_jpg():
56 print "print in jpg mode!"
57
58