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、数据科学、人工智能等文章后续会不定期发布,请大家多多关注,一键三连哟(●’◡’●)。