工厂模式是一种创建型模式,创建型模式主要解决对象的创建问题,封装复杂的创建过程,解耦对象的创建代码和使用代码
以下面为例,比如需要创建Section对象,类定义如下
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')
非工厂模式
如果不实用简单工厂方法,代码应该如下
if __name__ == '__main__':
# 创建和使用在一起
# 创建对象
if section_type == 'Personal':
section = PersonalSection()
elif section_type == 'Album':
section = AlbumSection()
# 使用对象
section.describe()
简单工厂(Simple Factory)
允许接口创建对象,但不会暴露对象的创建逻辑
# 假设创建的逻辑很复杂,那么将创建的逻辑解耦出来
class SectionFactory:
def create_section(self, section_type):
if section_type == 'Personal':
section = PersonalSection()
elif section_type == 'Album':
section = AlbumSection()
return section
if __name__ == '__main__':
sf = SectionFactory()
section = sf.create_section(section_type)
section.describe()
# SectionFactory实现 版本2, 通过eval来去掉ifelse逻辑
class SectionFactory:
def create_section(self, section_type):
return eval(f'{section_type}Section')()
# SectionFactory实现 版本3, 通过mapping方式
class SectionFactory:
section_mapping = {
'Personal': PersonalSection,
'Album': AlbumSection
}
def create_section(self, section_type):
section = self.section_mapping.get(section_type)
return section()
工厂模式(Factory Method)
当对象本身过于复杂的时候,使用工厂模式。怎么复杂呢?
比如,创建LinkedIn和Facebook Profile 对象
class LinkedInProfile:
# PersonalSection
# PatentSection
# PublicationSecton
class FacebookProfile:
# PersonalSection
# AlbumSection
我们发现这两个对象有一些共性,根据单一职责原则,将对象拆成更小的粒度,这样更好的复用。
对象分拆如下
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')
创建LinkedIn和Facebook 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 or FaceBook]')
profile = eval(profile_type.lower())()
print('creating Profile..', type(profile).__name__)
print('Profile has sections -- ', profile.getSections())
抽象工厂模式
在简单工厂和工厂方法中, 类只有一种分类方式,比如PersonalSection, AlbumSection都是属于Section
但是如果对于LinkedIn和Facebook来说PersonalSection和AlbumSection的具体实现不一致,代码如下
from abc import ABCMeta, abstractmethod
class PersonalSection(metaclass=ABCMeta):
@abstractmethod
def describe(self):
print('Personal Section')
class AlbumSection(metaclass=ABCMeta):
@abstractmethod
def describe(self):
print('Album Section')
class LinkedInPersonalSection(PersonalSection):
def describe(self):
print('LinkedIn Personal Section')
class FacebookPersonalSection(PersonalSection):
def describe(self):
print('Facebook Personal Section')
class LinkedInAlbumSection(AlbumSection):
def describe(self):
print('LinkedIn album section')
class FacebookAlbumSection(AlbumSection):
def describe(self):
print('Facebook album section')
这样的话,类有两种分类方式PersonalSection和AlbumSection, 两个抽象类
如果使用工厂模式,为了保持单一职责原则,一个Factory method只能创建一类对象。所以两种抽象类,就需要个工厂类,根据不同的业务LinkedIn/Facebook, 会拓展4个类。如下
class PersonalFactory(Profile):
def createPersonalProfile(self):
pass
class AlbumFactory(Profile):
def createAlbumProfile(self):
pass
class LinkedInPersonalFactory(PersonalFactory):
def createPersonalProfile(self):
self.addSections(LinkedInPersonalSection())
class LinkedInAlbumFactory(AlbumFactory):
def createAlbumProfile(self):
self.addSections(LinkedInAlbumSection())
class FacebookPersonalFactory(Profile):
def createPersonalProfile(self):
self.addSections(FacebookPersonalSection())
class FacebookAlbumFactory(Profile):
def createAlbumProfile(self):
self.addSections(FacebookAlbumSection())
类太多了,会让代码难以维护。
抽象工厂就是来解决这个问题的,那么抽象工厂是怎么来创建对象的呢?
class ProfileFactory(metaclass=ABCMeta):
@abstractmethod
def create_personal_section(self):
pass
@abstractmethod
def create_album_section(self):
pass
class LinkedInProfileFactory(ProfileFactory):
def create_personal_section(self):
return LinkedInPersonalSection()
def create_album_section(self):
return LinkedInAlbumSection()
class FacebookProfileFactory(ProfileFactory):
def create_personal_section(self):
return FacebookPersonalSection()
def create_album_section(self):
return FacebookAlbumSection()
将不同类型的对象,放在一个Factory中,这样的话,就节省了很多类,因为过多的类会让系统难以维护。
抽象工厂模式的主要目的是提供一个接口来创建一系列相关对象, UML图如下