python设计模式:工厂模式

工厂模式是一种创建型模式,创建型模式主要解决对象的创建问题,封装复杂的创建过程,解耦对象的创建代码和使用代码

以下面为例,比如需要创建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图如下
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值