zoukankan      html  css  js  c++  java
  • Python设计模式

    前言

    • 抽象工厂设计模式是抽象方法的一种泛化。概括来说,一个抽象工厂是(逻辑上)一组工厂方法,其中的每个工厂方法负责产生不同种类的对象。

    现实生活的例子

    汽车制造业应用了抽象工厂的思想。冲压不同的汽车模型的部件(车门、仪表盘、车篷、挡泥板及反光镜等)所使用的机件是相同的 。机件装配起来的模型随时可配置,且易于改变。

    应用案例

    • 因为抽象工厂模式是工厂方法模式的一种泛化,所以它提供相同的好处:让对象的创建更容易追踪;将对象创建与使用解耦;提供优化内存占用和应用性能的潜力。
    • 抽象工厂的特点:在使用工厂方法时从用户视角通常是看不到的,那就是抽象工厂能够通过改变激活的工厂方法动态地(运行时)改变应用行为,,而不需要终止应用然后重新启动。

    代码实现

    想象一下,我们正在创造一个游戏,或者想在应用种包含一个迷你游戏让用户娱乐。我们希望至少包含两个游戏,一个面向孩子,一个面向成人。在运行时,基于用户输入,决定该创建哪个游戏并运行。游戏的创建部分由一个抽象工厂维护。

    从孩子的游戏说起,我们将该游戏命名为FrogWord。主人公时一只青蛙,喜欢吃虫子。每个英雄都需要一个好名字,在我们的例子中,这个名字在运行时由用户给定。方法interact_with()用于描述青蛙与障碍物(比如,虫子、迷宫或者其他青蛙)之间的交互。

    
    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'
    
    

    类FrogWord是一个抽象工厂,其主要职责是创建游戏的主人公和障碍物。区分创建方法并使其名字通用(比如,make_character()make_obstacle()),这让我们可以动态改变当前激活的工厂(也因此改变了当前激活的游戏),而无需进行任何代码变更。在一门静态语言中,抽象工厂是一个抽象类/接口,具备一些空方法,但在Python中无需如此,因为类型是在运行时检测的。

    class FrogWorld:
        def __init__(self, name):
            print(self)
            self.player_name = name
    
        def __str__(self):
            return '
    
    	-------- Frog World-----------'
    
        def make_character(self):
            return Frog(self.player_name)
    
        def make_obstacle(self):
            return Bug()
    
    

    WizardWorld游戏类似。在故事中唯一的区别是男巫战怪兽,而不是青蛙吃虫子!

    class Wizard:
        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 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 '
    	--------- Wizard World---------'
    
        def make_character(self):
            return Wizard(self.player_name)
    
        def make_obstacle(self):
            return Ork()
    
    
    

    类GameEnvironment是我们游戏的主入口。它接收factory作为输入,用其创建游戏的世界。方法play()则会启动hero和obstacle之间的交互

    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)
    
    

    函数validate_age()提示用户提供一个有效的年龄。如果年龄无效,则会返回一个元组,其第一个元素设置为False。如果年龄没有问题,元组的第一个元素则设置为True,但我们真正关心的是元组的第二个元素,也就是用户提供的年龄。

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

    最后一个要点是main()函数,该函数请求用户的姓名和年龄,并根据用户的年龄决定该玩哪个游戏。

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

    抽象工厂实现的完整代码

    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 '
    
    	-------- 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 Frog encounters {} 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 '
    	--------- 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):
        age = input("Welcome {}. How old are you? ".format(name))
        try:
            age = int(age)
            return True, age
    
        except ValueError:
            print("Age {} is invalid, please try again...".format(age))
            return False, age
    
    
    def main():
        name = input("Hello. What's your name? ")
        valid_input = False
        age = None
        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()
    
  • 相关阅读:
    MOOK学习
    寒假学习计划
    三位影响深刻的老师
    软工第三次作业-结对作业
    2018软工实践第二次作业
    2018软工实践第一次作业
    简单的自我介绍
    福大软工1816 · 第一次作业
    课程作业八
    课程作业七
  • 原文地址:https://www.cnblogs.com/se7enjean/p/13701076.html
Copyright © 2011-2022 走看看