风清扬

导航

Python 设计模式之路(二)——简单工厂、工厂、抽象工厂模式

本节内容

  1. 简单工厂模式
  2. 工厂模式
  3. 抽象工厂模式
  4. 总结

一、简单工厂模式

业务分离:客户端和业务逻辑分离

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())

优点:

  1. 创建和使用对象的逻辑代码分离
  2. 实体对象暴露内容由接口控制

三、抽象工厂模式

# 披萨工厂基类
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 抽象工厂模式

四、总结

  1. 简单工厂不是23三种设计模式之一,因为太普通了,需要的东西打包成一个工厂(通常为函数)对外提供
  2. 工厂模式:一个产品对应一个工厂
  3. 抽象工厂:相关系列产品对应一个工厂,有多少个相关系列(可抽象成一个产品)即对应多少个工厂(抽象工厂)

 

 

 

posted on 2019-01-28 19:59  卜戈的博客  阅读(324)  评论(0编辑  收藏  举报