Python工厂模式一

工厂模式简介

在面向对象编程中,术语“工厂”表示一个负责创建其他类型对象的类。通常情况下,作为一个工厂的类有一个对象以及与它关联的多个方法。客户端使用某些参数调用此方法,之后,工厂会根据此创建所需类型的对象,然后将它们返回给客户端。

工厂具有的优点:

1、松耦合,即对象的创建可以独立于类的实现

2、客户端无需了解创建对象的类,但是照样可以使用它来创建对象。它只需要知道需要传递的接口、方法和参数,就能够创建所需类型的对象。这简化了客户端的实现。

3、可以轻轻松松的在工厂中添加其他类来创建其他类型的对象,而无需更改客户端代码,最简单的情况下,客户端只需要传递另一个参数就可以了。

4、工厂还可以重用现有对象。但是,如果客户端直接创建对象的话,总是创建一个新对象。

工厂模式有三种变体:

1、简单工厂模式:允许接口创建对象,但是不会暴露对象的创建逻辑。

2、工厂方法模式:允许接口创建对象,但是用哪个类来创建对象,则是交由子类决定的。

3、抽象工厂模式:抽象工厂是一个能够创建一系列相关的对象而无需指定/公开其具体类的接口。该模式能够提供其他工厂的对象,在其内部创建其他对象

简单工厂模式

对于一些人来说,简单工厂本身不是一种模式。开发人员再进一步了解这个概念之前,首先需要详细了解工厂方法和抽象工厂方法。工厂可以帮助开发人员创建不同类型的对象,而不是直接将对象实例化。

from abc import ABCMeta, abstractmethod


class Animal(metaclass=ABCMeta):
    @abstractmethod
    def do_say(self):
        pass


class Dog(Animal):
    def do_say(self):
        print("dog dog")


class Cat(Animal):
    def do_say(self):
        print("cat cat")


class ForestFactory(object):
    def make_sound(self, object_type):
        return eval(object_type)().do_say()


if __name__ == '__main__':
    ff = ForestFactory()
    animal = input("Dog or Cat?")
    ff.make_sound(animal)

在上面的代码中,我们创建一个名为Animal的抽象产品。Animal是一个抽象的基类(ABCMeta是Python的特殊元类, 用来生成类Abstract),它带有方法do_say().我们利用Animal接口创建了两种产品(Dog和Cat),并且实现了do_say()方法来提供这些动物相应的叫声。ForestFactory是一个带有make_sound()方法的工厂。根据客户端传递的参数类型,他就可以在运行时创建适当的Animal实例,并正确输出

 

工厂方法模式

通过以下几点了解工厂方法模式:

1、我们定义一个接口来创建对象,但是工厂本身并不负责创建对象,而是将这一任务由子类完成,即子类决定了要实例化那些类。

2、Factory方法的创建是通过继承而不是通过实例化来完成的。

3、工厂方法使设计更加具有可定制性。它可以返回相同的实例或子类,而不是某种类型的对象

实现工厂方法

我们拿一个现实世界的场景来理解工厂方法夫人实现。假设我们先想在不同类型的社交网站(例如Linkedin、Facebook等)上为个人或者公司建立简介。那么,每个简介都有某些特定的组成章节。在Linkedin的简介中,有一个章节是关于个人申请的专利或出版作品。在Facebook上,你将在相册中看到最近度假地点的照片区。此外,在这两个简介中,都有一个个人信息区。因此,我们要通过将正确的区添加到相应的简介中来创建不同类型的简介。

下面用代码去具体的实现,首先定义接口Product。我们将创建一个Section抽象类来定义一个区使关于哪方面内容的,让它尽量保持简单,同时还提供一个抽象方法describe()。

然后,我们会创建多个ConcreteProduct、PersonalSection、AlbumSection、PatentSection和PublicationSection类。这些类用于实现describe()抽象方法并打印它们各自的区名称:

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的抽象类Creator。Profile[Creator]抽象类提供一个工厂方法,createProfile()方法应该由ConcreteClass实现,来实际创建带有适当区的简介。Profile抽象类不知道每个简介应具有那些区。例如,Facebook的简介应该提供个人信息区和相册区。所以我们将让子类来决定这些事情。

我们创建两个ConcreteCreator类,即LinkedIn和Facebook。每个类都实现createProfile()抽象方法,由该方法在运行时实际创建多个区(ConcreteProducts):

class Profile(metaclass=ABCMeta):
    def __init__(self):
        self.sections = []
        self.create_profile()

    @abstractmethod
    def create_profile(self):
        pass

    def get_sections(self):
        return self.sections

    def add_sections(self, section):
        self.sections.append(section)


class LinkedIn(Profile):
    def create_profile(self):
        self.add_sections(PatentSection())
        self.add_sections(PatentSection())
        self.add_sections(PublicationSection())


class FaceBook(Profile):
    def create_profile(self):
        self.add_sections(PersonalSection())
        self.add_sections(AlbumSection())

最后开始写决定实例化那个Creator类的客户端代码,以便让它根据指定的选项创建所需的简介:

if __name__ == "__main__":
    profile_type = input("LinkedIn or FaceBook")
    profile = eval(profile_type)()
    print("Creating Profile.. ", type(profile).__name__)
    print("Profile has sections --", profile.get_sections())

工厂方法模式的优点:

1、它具有更大的灵活性,使得代码更加通用,因为它不是单纯地实例化某个类,这样实现那些类取决于接口。

2、它是松耦合的,因为创建对象的代码与使用它的代码是分开的。客户端完全不需要关心要传递那些参数以及需要实例化那些类。由于添加新类更加容易,所以降低了维护成本

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值