本文是参考实验楼的工厂模式总结,原文链接:https://www.shiyanlou.com/courses/356/learning/?id=1109
一、简单工厂模式(SimpleFactory)
import random
class BasicCourse(object):
"""
基础课程
"""
def start(self):
return "start BasicCourse"
def __str__(self):
return "BasciCourse"
class ProjectCourse(object):
"""
项目课
"""
def start(self):
return "start ProjectCourse"
def __str__(self):
return "ProjectCourse"
class SimpleCourseFactory(object):
@staticmethod
def create_course(course):
return BasicCourse() if course=='bc' else ProjectCourse()
使用简单工厂模式创建对象时,如果想要创建基础课,调用SimpleCourseFactory.create_course(course)方法时传入‘bc’,想要创建项目课则传入其他即可。以下代码随机创建一种课,并点击开始课程:
if __name__ == '__main__':
t = random.choice(['bc', 'pc'])
course = SimpleCourseFactory.create_course(t)
print(course)
print(course.start())
输出结果:
缺点
要扩展需要修改工厂代码,比如想要添加一门数学课程,除了需要增加数学类外(MathCourse),工厂方法需要修改为以下代码:
class SimpleCourseFactory(object):
@staticmethod
def create_course(course):
# return BasicCourse() if course=='bc' else ProjectCourse()
if course=='bc':
return BasicCourse()
elif course=='math':
return MathCourse()
else:
return ProjectCourse()
显而易见,这种简单工厂模式扩展起来不方便,如果要增加多个对象,得补充多个if分支。
工厂方法模式(Factory Method)
import random
import abc
class BasicCourse(object):
"""
基础课程
"""
def start(self):
return "start BasicCourse"
def __str__(self):
return "BasciCourse"
class ProjectCourse(object):
"""
项目课
"""
def start(self):
return "start ProjectCourse"
def __str__(self):
return "ProjectCourse"
# 使用abc模块定义抽象类和抽象方法,让实现类必须实现create_course方法
class Factory(metaclass=abc.ABCMeta):
@abc.abstractmethod
def create_course(self):
pass
class BasicCourseFactory(Factory):
def create_course(self):
return BasicCourse()
class ProjectCourseFactory(Factory):
def create_course(self):
return ProjectCourse()
还是随机选择一类课程,并开始:
if __name__ == '__main__':
factory = random.choice([BasicCourseFactory,ProjectCourseFactory])()
course = factory.create_course()
print(course)
print(course.start())
测试结果:
分析
相比于简单工厂类,工厂方法类扩展较为方便,比如还是想要添加数学类,不需要修改原有代码,只需要新增数学类和数学工厂类即可:
class MathCourse(object):
"""
项目课
"""
def start(self):
return "start MathCourse"
def __str__(self):
return "MathCourse"
class MathCourseFactory(Factory):
def create_course(self):
return MathCourse()
创建math对象,并开始课程:
if __name__ == '__main__':
# factory = random.choice([BasicCourseFactory,ProjectCourseFactory,MathCourse])()
course = MathCourseFactory().create_course()
print(course)
print(course.start())
测试成功:
三、抽象工厂模式(Abstract Factory)
其实这个和二没有本质区别。只是在抽象类factory中多定义了一个抽象方法。
现在假设有两类课程,基础课和项目,基础课需要在windows上操作,项目课需要在linux上操作。这里就有四个对象,基础课,项目课,win虚拟机,linux虚拟机,使用抽象工厂模式代码示例如下;
import random
import abc
class BasicCourse(object):
"""
基础课程
"""
def start(self):
return "start BasicCourse"
def __str__(self):
return "BasciCourse"
class ProjectCourse(object):
"""
项目课
"""
def start(self):
return "start ProjectCourse"
def __str__(self):
return "ProjectCourse"
class winVM():
def start(self):
return 'win vm start'
class LinuxVM():
def start(self):
return 'linux vm start'
class Factory(metaclass=abc.ABCMeta):
@abc.abstractmethod
def create_course(self):
pass
@abc.abstractmethod
def create_VM(self):
pass
class BasicCourseFactory(Factory):
def create_course(self):
return BasicCourse()
def create_VM(self):
return winVM()
class ProjectCourseFactory(Factory):
def create_course(self):
return ProjectCourse()
def create_VM(self):
return LinuxVM()
if __name__ == '__main__':
factory = random.choice([BasicCourseFactory,ProjectCourseFactory])()
course = factory.create_course()
vm=factory.create_VM()
print(course.start())
print(vm.start())
运行结果:可以看到开始基础课程就启动win虚拟机,开始项目课程就启动linux虚拟机。