简单工厂模式
简介
简单工厂模式,提供一个创建对象实例的功能,而无需关心其具体实现,属于创建型模式。适合对大量具有相同接口的类进行实例化,推迟到运行的时候才决定要创建哪个类的实例。简单工程的本质是选择实现。
示例:
写一个计算器控制台程序,要求输入两个数和运算符号,得到结果。
理由: 加减乘除法的都是对两个数进行运算,区别在于运算符不同,运算方式略有不同。
故可以用工厂模式,先创建一个运算类作为父类,然后继承运算类创建加减乘除4个子类。
下图是几种类的UML关系图。
Operation运算类---父类
class Operation:
numA = null
numB = null
def GetResult(self):
pass
加减乘除类---从运算类上继承过来
class OperationAdd(Operation):
def GetResult(self):
return self.numA + self.numB
class OperationSub(Operation):
def GetResult(self):
return self.numA - self.numB
class OperationMul(Operation):
def GetResult(self):
return self.numA * self.numB
class OperationDiv(Operation):
def GetResult(self):
try:
result = self.numA / self.numB
return result
except:
print "error: divided by zero"
return 0
class UndefOperator(Operator):
def GetResult(self):
print "error: undefined operator"
return 0工厂类---- 工厂实例化了合适的对象,通过多态,返回父类的方式实现了计算结果。
class OperationFactory:
operators = {}
operators['+'] = OperationAdd()
operators['-'] = OperationSub()
operators['*'] = OperationMul()
operators['/'] = OperationDiv()
def GetResult(self, ch):
if ch in operators:
op = operators[ch]
else:
op = UndefOperator()
return op
该工厂类的在C/C++中的switch/case语句来选择合适的对象,这里利用了字典的数据结构来代替。
优点是将运算符作为键,能快速的找到合适的实例化对象;缺点是为了构造这个字典把所有的运算符类型的对象都实例化了,增加了不必要的空间和时间上的浪费。
如果化成if/elif/else分支判断的话,每个条件都要进行判断,计算机做了很多无用功,时间上有些浪费;空间上只会实例化合适的类对象,没有空间上的浪费。
客户端主程序
if __name__ == '__main__':
oper = raw_input("operator is : ")
numA = raw_input("a: ")
numB = raw_input("b: ")
facotry = OperatorFactory()
cal = facotry.GetResult(oper)
cal.numA = numA
cal.numB = numB
cal.GetResult()
使用简单工厂模式完成的计算器,能够隔离运算符的变化,即使增加sin, cos 等其他运算符,客户端主程序都不需要变更,只需要在子类中增加一个类对象,然后在工厂类中的字典里增加相应的键值。
简单工厂的内部是实现了“选择合适的实现类”来创建实例对象。选择条件或参数的来源通常有以下几种:
客户端,有client传入参数
配置文件,从配置文件获取用于判断的值
程序运行期的某个值,比如缓存
简单工厂的优缺点
优点:
帮助封装----实现了组件的封装,让组件外部能真正面向对象编程
解耦----------通过简单工厂,实现了客户端和具体实现类的解耦。客户端无须知道具体的实现类,只要通过工厂获取它所需要的接口对象。 缺点:
可能增加客户端的负责度---------如果通过客户端来选择需要的实现类,那么客户端必须要了解它所选择的实现类的具体功能和含义
不方便扩展子工厂------------------通过静态方法来创建的接口,是不能通过简单的工厂类的子类来改变创建接口的行为。
与抽象工厂模式和工厂模式比较
简单工厂和抽象工厂模式 简单工厂是用来选择实现的,可以有多个用于选择并创建对象的方法。而抽象工厂模式是用来选择产品簇来实现的,一般有多个用于选择并创建对象的方法。
如果抽象工厂退化成为只有一个实现,就变成了简单工厂。
简单工厂和工厂方法模式 工厂方法把选择具体实现的功能延迟到子类去实现。如果把工厂方法中选择的实现放到父类直接实现,就等同于简单工厂。