平时大家上班都很累,为了增加工作中的欢乐气氛,黄页组准备搞个游戏。

游戏的名字是把大象关进冰箱。游戏很简单,需要把指定的物品放进冰箱。

我们都知道,把大象放进冰箱,分3步。

第一步,打开冰箱门,第二步,把大象放进去,第三步,关上冰箱。

但是,首先你的有一头大象,所以,人为又加了第零步,准备一只大象。

为了保证游戏的欢乐性,我们规定游戏者,在第二步把大象放进去的时候,需要有不同的表情动作等。

好,我并没有逗你玩。

游戏开始。

大雁同学很有兴趣。于是,我们编写一个简单的程序来实现这个过程。

写一个类.实现这个过程。

class PlayerDaisy:

    s_object = None

    def __init__(self):
pass def set_up(self):
PlayerDaisy.s_object = "大象"
print '准备一只大象 daisy 去了泰国买了一只', PlayerDaisy.s_object def step_one(self):
print '打开冰箱门' def step_two(self):
print '蹦蹦跳跳哭着,把大象放进冰箱' def step_three(self):
print '关上冰箱门'

if __name__ == "__main__":
daisy = PlayerDaisy()
daisy.set_up()
daisy.step_one()
daisy.step_two()
daisy.step_three()

运行结果:

菜菜,觉得挺好玩的于是也加入了游戏...

于是,我们继续编写代码

class PlayerYicai:

    s_object = None

    def __init__(self):
pass def set_up(self):
PlayerDaisy.s_object = "老虎"
print 'caicai 去了孟加拉买了一只', PlayerYicai.s_object def step_one(self):
print '打开冰箱门' def step_two(self):
print '歪歪扭扭笑着,把%s进冰箱' % PlayerYicai.s_object def step_three(self):
print '关上冰箱门'

然后高峰,羞羞....都觉得挺好玩的,都纷纷加入了游戏...

越来越多的人加入,于是,我们开始抄代码。。。复制,粘贴

情况有所不妙,抄得过程中,高峰忘记抄了step1, 没打开冰箱门。

结果鳄鱼,没法放进去了.....

羞羞忘记抄step3了,狮子,关进去,又出来了...

类似的情况越来越糟。

DRY:don't repeat yourself.

在这个缤纷的世界上,是否有东西,会永远不变?

谚语:

the only thing in the world that doesn't change is change itself.

所以,please DRY,也叫 DIE (duplication is evil)

上面的话,是我抄的。

重复是丑陋的,也是bug的温床。

ok, 那么我们可以尝试用模板方法模式来避免这种坏味道。

1. 概述

  定义一个操作中的算法的骨架,而将步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义算法的某些特定步骤。

2. 模式中的角色

  2.1 抽象类(AbstractClass):实现了模板方法,定义了算法的骨架。

  2.2 具体类(ConcreteClass):实现抽象类中的抽象方法,已完成完整的算法。

3. 模板方法类图:

那么,我们尝试改造代码。

首先,需要写一个基类。

由于开冰箱门和关冰箱门是固定的。所以定义抽象方法或虚方法第二步放物品。和准备物品。

我们还需定义一个公共的playgame方法。规定游戏的步骤,这样的话,就再也不会抄错啦。

子类必须实现父类的抽象方法。父类又定义了完成游戏的模板。

简直完美。

在python中 abc 模块(咦?为啥用个卫生巾的名字)实现了 抽象类和方法的功能。(我也是bing后才知道的)

使用了

@abc.abstractmethod装饰器的方法必须要在子类中实现

代码如下:

class PlayerBase(object):

    s_object = "未知东东"

    def __init__(self):
pass @abc.abstractmethod
def set_up(self):
pass def step_one(self):
print '打开冰箱门' @abc.abstractmethod
def step_two(self):
pass def step_three(self):
print '关上冰箱门' def play_game(self):
self.set_up()
self.step_one()
self.step_two()
self.step_three()

继承类。

class PlayerDaisy2(PlayerBase):
def __init__(self):
pass def set_up(self):
PlayerDaisy.s_object = "大象"
print '准备物品 去了买了一只', PlayerDaisy.s_object def step_two(self):
print '%s,把%s放进冰箱' % ('蹦蹦跳跳哭着', PlayerDaisy.s_object)
if __name__ == "__main__":
daisy = PlayerDaisy2()
daisy.play_game()

运行结果:

恩恩。。。太完美了。。。

模板方法模式就到这里。。

花了我几个小时写这篇文章。

构思都是在地铁上。

to be continued

[python实现设计模式]-2.模板方法模式---把大象关进冰箱.的更多相关文章

  1. 乐在其中设计模式(C#) - 模板方法模式(Template Method Pattern)

    原文:乐在其中设计模式(C#) - 模板方法模式(Template Method Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 模板方法模式(Template Method ...

  2. 折腾Java设计模式之模板方法模式

    博客原文地址:折腾Java设计模式之模板方法模式 模板方法模式 Define the skeleton of an algorithm in an operation, deferring some ...

  3. js设计模式——6.模板方法模式与职责链模式

    js设计模式——6.模板方法模式与职责链模式 职责链模式

  4. 命令式&函数式:把大象关进冰箱里问题

    面向过程:把大象关进冰箱里: 把冰箱门打开=> 大象放冰箱里=> 冰箱门关上 面向对象: 冰箱.开门() 冰箱.放入(大象) 冰箱.关门() 函数式: 关进(冰箱,大象): 关门(放入(开 ...

  5. Python笔记:设计模式之模板方法模式

    此模式通过一个模板方法来定义程序的框架或算法,通常模板方法定义在基类中,即原始的模板,然后子类就可以根据不同的需要实现或重写模板方法中的某些算法步骤或者框架的某部分,最后达到使用相同模板实现不同功能的 ...

  6. python 设计模式之模板方法模式

    1.模板方法模式定义 模板模式定义如下:定义一个操作中的算法的框架,而将一些步骤延迟到子类中,使得子类可以不改变一个算法的结构即可重新定义该算法的某些特定的步骤.子类实现的具体方法叫作基本方法,实现对 ...

  7. java设计模式之模板方法模式

    模板方法模式 定义一个操作中的算法的骨架,而将一些步骤延迟到子类中. 模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤.通俗的说的就是有很多相同的步骤的,在某一些地方可能有一些差 ...

  8. C#设计模式(14)——模板方法模式(Template Method)

    一.引言 提到模板,大家肯定不免想到生活中的“简历模板”.“论文模板”.“Word中模版文件”等,在现实生活中,模板的概念就是——有一个规定的格式,然后每个人都可以根据自己的需求或情况去更新它,例如简 ...

  9. 【GOF23设计模式】模板方法模式

    来源:http://www.bjsxt.com/ 一.[GOF23设计模式]_模板方法模式.钩子函数.方法回调.好莱坞原则 package com.test.templateMethod; publi ...

随机推荐

  1. WinForm DataGridView根据选中的复选框删除

    注意:在DataGridView添加一列(name:delete),ColumnType属性为:DataGridViewCheckBoxColumn,FlaseValue属性为:Flase,TureV ...

  2. 初用eclipse和svn遇见的问题以及解决方法

    第一次用eclipse 首先用SVN输入URI出现报错 去百度查了一下 大致就两点问题 1.防火墙的问题 2.SVN服务没开 我两个问题都不存在就去请教大神得到解决方案 解决方案:把URI的机器名改成 ...

  3. Spring 的 NamedParameterJdbcTemplate(转)

    NamedParameterJdbcTemplate类是基于JdbcTemplate类,并对它进行了封装从而支持命名参数特性. NamedParameterJdbcTemplate主要提供以下三类方法 ...

  4. thinkphp + 美图秀秀api 实现图片裁切上传,带数据库

    思路: 1.数据库 创建test2 创建表img,字段id,url,addtime 2.前台页: 1>我用的是bootstrap 引入必要的js,css 2>引入美图秀秀的js 3.后台: ...

  5. CI框架 CodeIgniter 伪静态 htaccess设置和Nginx伪静态方法2

    1.在根目录西下  新建.htaccess 文件 RewriteEngine on RewriteCond $1 !^(index\.php|images|robots\.txt) RewriteRu ...

  6. 解决oracle服务器重启之后连接报错的问题

    DB服务器重启之后再连接报错如下: 原因是重启之后listener.ora被还原成初始文件,sid被清空. 解决步骤: 1.查看监听服务和数据库服务: 由此找到listener.ora文件的路径:D: ...

  7. create dll project based on the existing project

    Today, I have to create a dll project(called my.sln), the dllmain.cpp/.h/ is already in another proj ...

  8. 【转载】Ansys中的阻尼

    原文地址:http://www.cnblogs.com/ylhome/archive/2009/08/26/1554195.html ANSYS动力学分析中提供了各种的阻尼形式,这些阻尼在分析中是如何 ...

  9. Qt开发中的实用笔记三--关于各种类的零碎知识点:

    1,QUuid()创建唯一标识码,在创建数据库实体ID和链接数据库QSqlDatabase时非常方便 2,QScrollArea与QScrollBar,如果是要在widget中添加窗口滑动QScrol ...

  10. ASP.NET Web 应用程序及页面生命周期

    以客户端浏览器向 ASP.NET Web 应用程序页面发送请求(Request)为起点,以浏览器收到 Web 服务器的响应(Response)为终点,这一完整的过程被称为"应用程序及页面的生 ...