Python 设计模式之路(二)——简单工厂、工厂、抽象工厂模式
本节内容
- 简单工厂模式
- 工厂模式
- 抽象工厂模式
- 总结
一、简单工厂模式
业务分离:客户端和业务逻辑分离
from abc import ABCMeta, abstractmethod # 抽象动物类 class Animal(metaclass = ABCMeta): @abstractmethod def do_say(self): pass # 狗类,继承动物类 class Dog(Animal): def do_say(self): print("Bhow Bhow!!") # 猫类,继承动物类 class Cat(Animal): def do_say(self): print("Meow Meow!!") ## forest factory defined class ForestFactory(object): def make_sound(self, object_type): print(eval(object_type)) return eval(object_type)().do_say() ## client code if __name__ == '__main__': ff = ForestFactory() animal = input("Which animal should make_sound Dog or Cat?") ff.make_sound(animal)
缺点
- 工厂类的职责过重,即对象创建和使用逻辑在一起
二、工厂模式
# 工厂模式 # 需求:有两个社交媒体Linkedin ,Facebook.他们都要取人的简历信息(相册,专利等等。。)但是展示方式不一样 from abc import ABCMeta, abstractmethod # 抽象基类(部分类) class Section(metaclass=ABCMeta): @abstractmethod def describe(self): pass # 子类,继承基类(个人部分类) class PersonalSection(Section): def describe(self): print("Personal Section") # 子类,继承基类(专辑部分类) class AlbumSection(Section): def describe(self): print("Album Section") # 子类,继承基类(专利部分类) class PatentSection(Section): def describe(self): print("Patent Section") # 子类,继承基类(出版部分类) class PublicationSection(Section): def describe(self): print("Publication Section") # 工厂方法类:只提供了接口,并没有实际创建类(Profile类:提供Profile中的接口) class Profile(metaclass=ABCMeta): def __init__(self): self.sections = [] self.createProfile() @abstractmethod def createProfile(self): pass def getSections(self): return self.sections def addSections(self, section): self.sections.append(section) class linkedin(Profile): def createProfile(self): self.addSections(PersonalSection()) self.addSections(PatentSection()) self.addSections(PublicationSection()) class facebook(Profile): def createProfile(self): self.addSections(PersonalSection()) self.addSections(AlbumSection()) if __name__ == '__main__': profile_type = input("Which Profile you'd like to create? [LinkedIn orFaceBook]") profile = eval(profile_type.lower())() print("Creating Profile..", type(profile).__name__) print("Profile has sections --", profile.getSections())
优点:
- 创建和使用对象的逻辑代码分离
- 实体对象暴露内容由接口控制
三、抽象工厂模式
# 披萨工厂基类 class PizzaFactory(metaclass=ABCMeta): @abstractmethod def createVegPizza(self): pass @abstractmethod def createNonVegPizza(self): pass # 印度披萨工厂 class IndianPizzaFactory(PizzaFactory): def createVegPizza(self): return DeluxVeggiePizza() def createNonVegPizza(self): return ChickenPizza() # 美国披萨工厂 class USPizzaFactory(PizzaFactory): def createVegPizza(self): return MexicanVegPizza() def createNonVegPizza(self): return HamPizza() # 蔬菜披萨 class VegPizza(metaclass=ABCMeta): @abstractmethod def prepare(self, VegPizza): pass # 没有蔬菜的披萨 class NonVegPizza(metaclass=ABCMeta): @abstractmethod def serve(self, VegPizza): pass # 多彩蔬菜披萨 class DeluxVeggiePizza(VegPizza): def prepare(self): print("Prepare ", type(self).__name__) # 鸡肉披萨 class ChickenPizza(NonVegPizza): def serve(self, VegPizza): print(type(self).__name__, " is served with Chicken on ",type(VegPizza).__name__) # 墨西哥蔬菜披萨 class MexicanVegPizza(VegPizza): def prepare(self): print("Prepare ", type(self).__name__) # 火腿披萨 class HamPizza(NonVegPizza): def serve(self, VegPizza): print(type(self).__name__, " is served with Ham on ",type(VegPizza).__name__) # 披萨商店类 class PizzaStore: def __init__(self): pass def makePizzas(self): for factory in [IndianPizzaFactory(), USPizzaFactory()]: self.factory = factory self.NonVegPizza = self.factory.createNonVegPizza() self.VegPizza = self.factory.createVegPizza() self.VegPizza.prepare() self.NonVegPizza.serve(self.VegPizza) pizza = PizzaStore() pizza.makePizzas()
工厂模式 VS 抽象工厂模式
四、总结
- 简单工厂不是23三种设计模式之一,因为太普通了,需要的东西打包成一个工厂(通常为函数)对外提供
- 工厂模式:一个产品对应一个工厂
- 抽象工厂:相关系列产品对应一个工厂,有多少个相关系列(可抽象成一个产品)即对应多少个工厂(抽象工厂)