【“笨办法”学Python】43.基本的面向对象分析和设计——自顶向下、自底向上

43.基本的面向对象分析和设计



前言

  使用Python,尤其是通过面向对象编程(OOP)方式构建一些东西的流程。


一、解决问题的方法——流程

  所谓按照流程就是遵循一系列的步骤,但是并不意味着对每个不同的问题都要用这个步骤,也并不意味着这个步骤总是能起作用。这些步骤只是解决很多编程问题的一个很好的起点,并不是解决这类问题的唯一方法。

1、自顶向下(top down)

  自顶向下(top down)的过程一般是从做抽象的概念(顶层)开始,一直向下做到具体的代码实现。具体流程如下:
(1) 把要解决的问题写下来,或者画出来
(2) 将第一条中的关键概念提取出来并加以研究
(3) 创建一个类层次结构和对象图
(4) 用代码实现各个类,并写一个测试来运行它们
(5) 重复上述步骤并细化代码

2、自底向上

  自底向上就是先从代码开始,一直向上做到抽象概念。具体流程如下:
(1) 取出要解决的问题中的一小块,写一些代码让它基本可以工作
(2) 加上类和自动测试,细化代码让他更为正式
(3) 把关键概念抽取出来然后研究它们
(4) 把真正需要实现的东西描述出来
(5) 回去细化代码,有可能需要全部丢弃从头做起
(6) 在问题的另一小块里重复上述流程


二、代码示例

  《来自Peracl 25号行星的哥顿人》的代码:

#coding:utf-8
from sys import exit
from random import randint
from textwrap import dedent

class Scene(object):

    def enter(self):
        print("此场景尚未配置!")
        print("子类化它并实现enter().")
        exit(1)

class Engine(object):

    def __init__(self,scene_map):   #scene_map是Map类的
        self.scene_map = scene_map

    def play(self):
        current_scene = self.scene_map.opening_scene()
        last_scene = self.scene_map.next_scene('finished')
        while current_scene != last_scene:                    #返回的都是场景的类
            next_scene_name = current_scene.enter()         #返回的都是场景的类对应的key
            current_scene = self.scene_map.next_scene(next_scene_name)
        current_scene.enter()

class Death(Scene):

    quips = ["你死了", "你在这有点糟糕", "干得漂亮,你死了,愚蠢的人类", "失败者", "我有只小狗很擅长这个"]
    def enter(self):
        print (Death.quips[randint(0,len(self.quips)-1)])
        exit(1)

class CentralCorridor(Scene):

    def enter(self):
        print (dedent("""
        Percal25号行星的哥顿人入侵了你的飞船,摧毁了你的全体船员。
        你是最后一个幸存的成员,你的最后一个任务是从武器库取出中子毁灭性炸弹,放在舰桥上,进入逃生舱后炸毁飞船。
        你正沿着通往武器库的中央走廊奔跑,这时一个哥顿人跳了出来,皮肤发红,牙齿发黑,邪恶的小丑服装在他那带帽的身体上飘荡。
        他堵住了军械库的门,准备拔出武器来炸你.
        """))

        action =input("> ")

        if action == "shoot":
            print (dedent("""
            快速抽签,即可取出爆破器并向Gothon发射。
            他的小丑服装在他的身上四处流动,这使你无法瞄准。
            你的激光打中了他的服装,但完全没有击中他。
            这完全毁了他母亲买给他的崭新服装,这使他疯狂地飞起来,反复地对着你炸开,直到你死了。
            然后他吃了你。
            """))
            return "death"

        elif action == "dodge":
            print (dedent("""
            就像一个世界级的拳击手,你躲闪、编织、滑动和滑动,就像哥顿的爆破者用激光从你的头上划过一样。
            在你的巧妙的中间,你的脚滑倒,你的头撞到精神墙上,昏倒了。
            你醒来后不久就死了,因为哥顿跺着你的头吃了你
            """))
            return "death"

        elif action == "tell a joke":
            print (dedent("""
            幸运的是,它们使您在学院里学习了哥德的侮辱。
            你讲了一个你知道的Gothon笑话:Lbhe zbgure vf fb sng , jura fur fgf nebhag gur ubhfrfur fgf nebhag gur ubhfr .
            Gothon停了下来,试着不笑,然后突然大笑起来,动弹不得。
            当他在笑的时候,你跑上前朝他头部开了一枪,把他打倒在地,然后跳过武器库的门。
            """))
            return "laser_weapon_armory"

        else:
            print ("别想了")
            return 'central_corridor'

class LaserWeaponArmory(Scene):

    def enter(self):
        print (dedent("""
        你向武器库俯冲,蹲下并扫视房间,寻找更多可能藏匿的哥顿人。
        这里死气沉沉的,太安静了。 你站起来,跑到房间的另一边,发现中子弹在它的容器里。
        盒子上有个小键盘锁,你需要密码才能把炸弹取出来。
        如果你把代码错了10次,那么锁就会永远关闭,你就拿不到炸弹了。
        密码是3位数字
        """))

        code = f"{randint(1,9)}{randint(1,9)}{randint(1,9)}"
        # code = "636"
        guess = input("[keypad]> ")
        guesses = 0

        while guess != code and guesses < 10:
            print ("BZZZZEDDD!")
            guesses += 1
            guess = input("[keypad]> ")

        if guess == code:
            print (dedent("""
            容器咔嗒一声打开,密封破裂,释放气体。
            你抓住中子弹,尽可能快地跑到桥上,你必须把它放在正确的位置。
            """))
            return "the_bridge"

        else:
            print (dedent("""
            锁最后一次嗡嗡作响,然后当机械融合在一起时,你会听到一种令人恶心的融化的声音。
            你决定坐在那里,最后哥特人炸毁了他们的船,你就死定了。
            """))
            return "death"

class TheBridge(Scene):

    def enter(self):
        print (dedent("""
        你手臂下夹着尼特龙自毁炸弹冲进舰桥,让5个试图控制飞船的哥特人大吃一惊。
        他们每个人都有比上一个更丑的小丑服装。
        他们还没有拿出武器,因为他们看到你腋下的炸弹很活跃,不想引爆它。
        """))
        action = input("> ")

        if action == "throw the bomb":
            print (dedent("""
            你惊慌失措地把炸弹扔给一群哥特人,然后向门口扑去。
            就在你掉下去的时候,一个哥顿朝你的后背开枪杀了你。
            当你死后,你看到另一个哥特人疯狂地试图解除炸弹的武装。
            你死的时候知道他们很可能会在它爆炸的时候降落。
            """))
            return "death"

        elif action == "slowly place the bomb":
            print (dedent("""
            你用爆能枪指着腋下的炸弹,哥特人举起手开始出汗。
            你向后退一步,打开门,然后小心地把炸弹放在地板上,用爆炸机对准它。
            然后你从门里跳回来,按一下关门按钮,然后打开门锁,这样哥特人就不能出去了。
            既然炸弹放好了,你就跑去逃生舱,从这个罐头罐上下来。
            """))
            return "escape_pod"

        else:
            print("别想了")
            return "the_bridge"

class EscapePod(Scene):

    def enter(self):
        print (dedent("""
        你拼命地冲过船,试图在整个船爆炸之前使其到达逃生舱。
        似乎船上几乎没有哥特人,因此你的奔跑没有干扰。
        你带着逃生舱进入密室,现在需要选择一个来逃生。
        其中一些可能已损坏,但您没有时间看。
        有5个吊舱,您要拿哪一个?
        """))

        good_pod = randint(1, 5)
        # good_pod = 3
        guess = input("[pod #]> ")


        if int(guess) != good_pod:
            print (dedent("""
            你跳进 {guess} 号逃生仓,按下了弹出按钮
            吊舱从太空中逃出来,然后在船体破裂时内爆,把你的身体压成果酱果冻。
            """))
            return "death"

        else:
            print (dedent("""
            你跳入吊舱(猜猜)并按下弹出按钮。
            太空舱很容易滑入太空,向下面的行星前进。
            当它飞向这个星球时,你回过头来,看到你的飞船内爆,然后像一颗明亮的恒星一样爆炸,同时把哥顿飞船炸掉。你赢了!
            """))
            return "finished"

class Finished(Scene):

    def enter(self):
        print("你赢了!干得漂亮!!!")
        return "finished"

class Map(object):

    scenes = {
        'death':Death(),
        'central_corridor':CentralCorridor(),
        'laser_weapon_armory':LaserWeaponArmory(),
        'the_bridge':TheBridge(),
        'escape_pod':EscapePod(),
        'finished':Finished()
        }

    def __init__(self,start_scene):
        self.start_scene=start_scene                # 确定开始的场景

    def next_scene(self,scene_name):
        val=Map.scenes.get(scene_name)
        return val                                  # 返回scenes字典中所有对应的类

    def opening_scene(self):
        return self.next_scene(self.start_scene)    # 返回开始场景在scenes字典中对应的类


a_map = Map('central_corridor')
# print(a_map)
a_game = Engine(a_map)
a_game.play()


三、运行Python程序

  在Window上键入Python就可以看到结果。依次输入:tell a joke 、密码 、slowly place the bimb 、救生吊舱号码,就能获得游戏胜利!

python ex43.py

请添加图片描述


总结

  以上内容介绍了基本的面向对象分析和设计,有关Python、数据科学、人工智能等文章后续会不定期发布,请大家多多关注,一键三连哟(●’◡’●)。

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
【大纲】 0-1-课程内容和安排介绍 1-1-计算机的概念 1-2-程序设计语言概述 1-3-Python语言 1-4-Python开发环境配置 1-5-基本程序设计方法 1-6-理解问题的计算部分 1-7-温度转换程序实例 2-1-Python程序元素分析 2-2-程序编写模板 2-3-turtle库和蟒蛇绘制程序 2-4-蟒蛇绘制程序分析 2-5-函数库的引用 3-1-Python中类型的概念 3-2-数字类型 3-3-字符串类型 3-4-字符串的操作 3-5-元组类型 3-6-列表类型及操作 3-7-math库和random库 3-8-π的计算 4-1-1-程序基本结构 4-1-2-简单分支 4-1-3-多分支 4-1-4-异常处理设计 4-1-5-三者最大实例分析 4-2-1-基本循环结构 4-2-2-通用循环构造方法 4-2-3-死循环半路循环 4-2-4-布尔表达式 6-1-1-文件的基础 6-1-2-文件的基本处理 6-1-3-文件实例一 6-1-4-文件实例二 6-2-1-字典的基础 6-2-2-字典的操作 6-2-3-字典实例一 6-2-4-字典实例二 7-3-1-计算思维 7-3-2-自顶向下设计 7-3-3-自底向上的执行 7-3-4-软件工程 7-3-5-敏捷开发方法 7-4-1-面向过程的程序设计 7-4-2-面向对象的程序设计 7-4-3-基本例子 7-4-4-面向对象的特点 8-6-1-基本介绍 8-6-2-图形对象概念 8-6-3-交互式图形用户接口 8-6-4-图形库的应用方法 8-6-5-Turtle库介绍 8-6-6-图形用户接口实例 8-6-7-Turtle实例 8-6-8-Turtle Art 第6章-函数与递归-1-函数定义 第6章-函数与递归-2-函数的调用和返回值 第6章-函数与递归-3-改变参数值的函数 第6章-函数与递归-4-程序结构和递归 第6章-函数与递归-5-函数实例

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

机器视觉小学徒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值