python学习-设计模式之-工厂模式

一、工厂方法

(一)工厂模式运用场景

  • 如果因为应用创建对象的代码分布在多个不同的地方,而不是仅在一个函数/方法中,你发 现没法跟踪这些对象,那么应该考虑使用工厂方法模式。

    • 有一个工厂方法负责连接到不同的数据库(MySQL、SQLite)。
    • 另一个工厂方法负责创建要求的 几何对象(圆形、三角形)。
  • 若需要将对象的创建和使用解耦,工厂方法也能派上用场。
  • 工厂方法可以在必要时创建新的对象,从而提高性能和内存使用率。

(二)工厂模式案例

import xml.etree.ElementTree as etree
import json

class JSONConnector:
    def __init__(self, filepath):
        self.data = dict()
        with open(filepath, mode='r') as f:
            self.data = json.load(f)
    @property
    def parsed_data(self):
        return self.data

class XMLConnector:
    def __init__(self, filepath):
        self.tree = etree.parse(filepath)
    @property
    def parsed_data(self):
        return self.tree

def connection_factory(filepath):
    if filepath.endswith('json'):
        connector = JSONConnector
    elif filepath.endswith('xml'):
        connector = XMLConnector
    else:
        raise ValueError('Cannot connect to {}'.format(filepath))
    return connector(filepath)

def connect_to(filepath):
    factory = None
    try:
        factory = connection_factory(filepath)
    except ValueError as ve:
        print(ve)
    return factory

if __name__ == '__main__':
    # 要那个传哪个,不占用内存
    sqlite_factory = connect_to('person.sq3')
    xml_factory = connect_to('person.xml')
    json_factory = connect_to('person.json')

二、抽象工厂

(一)什么事抽象工厂

一个抽象工厂是(逻辑上的)一组工厂方法,其中的每个工厂方法负责产生不同种类的对象。

(二)应用场景

  • 程序包django_factory是一个用于在测试中创建Django模型的抽象工厂实现,可用来为支持测试专有属性的模型创建实例。这能让测试代码的可读性更高,且能避免共享不必要的代码,故有其存在的价值。
  • 通常一开始时使用工厂方法,因为它更简单。如果后来发现应用需要许多工厂方法,那么将创建一系列对象的过程合并在一起更合理,从而最终引入抽象工厂。
  • 抽象工厂能够通过改变激活的工厂方法动态地(运行时)改变应用行为。

(三)应用案例

class Frog:    # 青蛙类
    def __init__(self, name):
        self.name = name
    def __str__(self):
        return self.name
    def interact_with(self, obstacle):
        print('{} the Frog encounters {} and {}!'.format(self,
        obstacle, obstacle.action()))

class Bug:   # 虫子类
    def __str__(self):
        return 'a bug'
    def action(self):
        return 'eats it'

class FrogWorld:  # 青蛙游戏
    def __init__(self, name):
        print(self)
        self.player_name = name
    def __str__(self):
        return '\n\n\t------ Frog World -------'
    def make_character(self):
        return Frog(self.player_name)
    def make_obstacle(self):
        return Bug()

class Wizard:  # 男巫类
    def __init__(self, name):
        self.name = name
    def __str__(self):
        return self.name
    def interact_with(self, obstacle):
        print('{} the Wizard battles against {} and {}!'.format(self, obstacle, obstacle.action()))

class Ork:  # 兽人
    def __str__(self):
        return 'an evil ork'
    def action(self):
        return 'kills it'

class WizardWorld:  # 男巫游戏
    def __init__(self, name):
        print(self)
        self.player_name = name

    def __str__(self):
        return '\n\n\t------ Wizard World -------'

    def make_character(self):
        return Wizard(self.player_name)

    def make_obstacle(self):
        return Ork()

class GameEnvironment:
    def __init__(self, factory):
        self.hero = factory.make_character()
        self.obstacle = factory.make_obstacle()

    def play(self):
        self.hero.interact_with(self.obstacle)

def validate_age(name):
    try:
        age = raw_input('Welcome {}. How old are you? '.format(name))
        age = int(age)
    except ValueError as err:
        print("Age {} is invalid, please try again...".format(age))
        return (False, age)
    return (True, age)

def main():
    name = raw_input("Hello. What's your name? ")
    valid_input = False
    while not valid_input:
        valid_input, age = validate_age(name)
    game = FrogWorld if age < 18 else WizardWorld
    environment = GameEnvironment(game(name))
    environment.play()

if __name__ == '__main__':
    main()

猜你喜欢

转载自blog.csdn.net/zhangmoyan9527/article/details/82077808