版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/jdhellfire/article/details/78380672
工厂模式:给所有产品抽象出一个公共的接口,工厂类根据需要实例化不同的产品。
《大话设计模式》这本书中给出实现计算器运算例子:
一.简单工厂的好处分析如下:
1.将所有算法抽象出一个公共基类“运算类”,提供GetResult公共接口。工厂类根据需要实例化不同的“产品”即具体的算法。而客户端只需要调用公共的GetRestult算法完成计算即可。运算类的扩展不会影响到客户端计算的逻辑。
2.抽象出简单工厂类后,算法对象的创建被集中化,使得算法对象的创建和使用解耦。
二.简单工厂的缺点:
工厂类中存在Switch或if ….else的结构,使得功能的演进偶可能对原有代码产生波及,违背了“开放封闭原则”。
三.示例:
下面分别用Python和ITcl语言演示简单工厂,为了代码不依赖具体项目上下文环境,便于理解,例子很简单。这里要实现一个关于“打球”的文本打印,球的种类可能有多种,根据不同类型打印不同的字样。
Python实现示例子
from abc import ABCMeta, abstractmethod
class Ball:
@abstractmethod
def play(self): pass
class Football(Ball):
def play(self):
print('play Football')
class VollyBall(Ball):
def play(self):
print('play Volleyball')
class Basketball(Ball):
def play(self):
print('play Basketball')
class BallSelecter:
def __init__(self, type):
self.__type = type
def get_ball(self):
if self.__type == 'Football':
return Football()
elif self.__type == 'Volleyball':
return VollyBall()
elif self.__type == 'Basketball':
return Basketball()
else:
return None
myball = BallSelecter('Basketball').get_ball()
myball.play()
ITcl实现示例子
itcl::class Ball {
#打球的公共接口
public method Play {} {}
}
itcl::class FootBall {
public method Play {} {puts "play FootBall"}
destructor {
puts "FootBall destroy"
}
}
itcl::class VollyBall {
public method Play {} {puts "play VollyBall"}
destructor {
puts "VollyBall destroy"
}
}
itcl::class Factory {
constructor {} {
# 确保抽象类不能被初始化
if {[namespace tail [info class]] == "Factory"} {
error "Error: can't create Factory objects - abstract class."
}
}
#强调内容*#强调内容*#在Incr Tcl里,工厂方法实现了在父类的名词空间里创建对象的方式。
#在下面这个工的例子里,尽管你想要在方法被调用的名词空间
#里创建新的对象,
#尽管通常情况下是在全局名词空间内,但也有可能是其它任何地方,所
#以我们使用uplevel命令确保
#在方法被调用的名词空间内创建对象。并且使用namespace which获得
#该对象可以传递到其它任何名词空间的对象名字。
public proc CreatOperate { XinBie } {
#itcl::local Ball b
#Ball b
switch $XinBie {
"Nan" {
return [uplevel {namespace which [FootBall #auto]}]
#return [FootBall #auto]
}
"Niu" {
#::test::vollyBall0
return [uplevel {namespace which [VollyBall #auto]}]
#return [VollyBall #auto]
}
}
return $b
}
}
set Select "Niu"
namespace eval test {
#Ball b
set b [Factory::CreatOperate $Select]
#::test::vollyBall0
puts $b
$b Play
}