原标题:为什么Python不用设计模式?

来自:码农翻身(微信号:coderising)

在遥远的Python王国,有一位少年,非常热爱编程,他的父母想给他报一个班,问了万能的朋友圈以后,发现大家都推荐同一个老师,人称吉先生。

于是他的父母毫不犹豫就交了一笔不菲的学费,每周六日下午让孩子去学习。

少年学习非常刻苦,很快就学会了Python语法、工具和框架。

老师像是见到了可以雕刻的美玉, 倾囊相授,告诉他不仅要把代码写对,还要让代码漂亮、优雅、可读、可维护。

少年又学会了单元测试,TDD,重构,努力让自己的代码达到老师所要求的标准。

他还把“Python 之禅”贴在了自己的墙上,经常对照自己的代码,从来都不敢违反。

The Zen of Python, by Tim Peters

Beautiful is better than ugly.

Explicit is better than implicit.

Simple is better than complex.

Complex is better than complicated.

Flat is better than nested.

Sparse is better than dense.

Readability counts.

......

三年以后,少年以为自己成为了Python的大师,直到有一天,老师给他布置了一个大作业,其实是个大项目,业务非常复杂。

少年通宵达旦地编程,可他悲惨地发现,无论他怎么努力,他的代码都是乱糟糟的,没有美感,他所写出的类,模块混成了一团。

于是他只好去请教老师: “老师,我的Python和Flask框架已经用得滚瓜烂熟了,为什么完成不了这个项目呢?”

老师说:“孩子,原来你只需要把框架的类给import进来,稍微写点儿代码就行了,现在你需要自己去设计类,自己去做出抽象了!”

“怎么设计呢?”

“为师送你一本古书,《设计模式》 ,你回去好好看看吧。”

少年如获至宝, 废寝忘食地去研究这本20多年前出的、泛黄的古书,还是用C++描述的。

他看得云里雾里,似乎明白,又似乎不明白,只好再去请教老师。

这一次,老师给了他另外一本书, 《Head First 设计模式》

少年翻开一看,这本书是用Java写的,于是又一头扎到了Java语言当中。

这本书比较通俗易懂,少年看得大呼过瘾。

终于,他信心十足地用Python开始那个大项目了。

他用Python语言实现设计模式,解决一些设计问题,可是总觉得不对劲,和Java , C++相比,感觉怪怪的。

另外他感觉到了动态语言的不爽之处,每次想重构的时候,总是不敢下手,他把困惑给老师说了。

老师笑道:“我在Java王国的时候,人们总是说‘动态一时爽,重构火葬场’, 现在你体会到了吧!”

“Java就能避免这个问题吗?”

“Java是一门静态语言,变量类型一旦确定就不能改变,对重构的支持非常好,你有没有兴趣去看看?那里有很多的框架,像Spring,Spring Boot,MyBatis, Dubbo, Netty,非常繁荣发达。”

少年心生向往,于是老师就给他写了个条子,告诉他说到了Java王国,找到IO大臣,一切事情都会畅通无阻。

少年辞别老师,奔向了Java帝国,老师整了整衣冠, 望着东方Java帝国的方向,庄严地拜了三拜:“五年了,IO大人,我没有辜负您的重托,又忽悠了一个人去做Java了!”

原来这位老师就是吉森! IO大臣派来传播Java文化和价值观的传教士,入境后不幸被识破,软禁在了Python王国。

吉森的故事请移步《Java帝国对Python的渗透能成功吗?》

Python没有接口?

Python国王收到边关的奏报,说是最近有不少年轻人奔向了Java王国,不知道是不是国内政策有变,导致人心浮动。

Python国王震怒,下令严查。查来查去,所有的线索都指向了一个人:吉森。

这一天,Python特使带着士兵来到了吉森的住所,果然发现他又在忽悠年轻人了。

特使又气又笑:“你学了半吊子的Python,居然敢来蛊惑人心,实在是可笑。”

吉森看到自己的计谋已被识破,依然很镇静:“大人误会了,我教的就是正宗的面向对象的设计和设计模式啊,这设计模式用Python实现起来很别扭,我就推荐他们去学Java啊。”

“胡说,Python写设计模式怎么会很别扭? Java 由于语法所限,表达能力比较弱,对于一些问题,只好用笨拙的设计模式来解决,我们Python有可能在语法层面就解决问题了!”

“那你说说,设计模式的原则是什么?” 吉森问道。

“1. 面向接口编程,而不是面向实现编程。2. 优先使用组合而不是继承。” 这是难不住特使的。

“Python连接口都没有,怎么面向接口编程?” 吉森问道。

特使哈哈大笑:“说你是半吊子吧,你还不服,你以为这里的接口就是你们Java的interface啊!你忘了Python的Duck Typing了?”

classDuck:

deffly(self):

print( "Duck flying")

classAirplane:

deffly(self):

print( "Airplane flying")

deflift_off(entity):

entity.fly()

duck = Duck()

plane = Airplane()

lift_off(duck)

lift_off(plane)

“看到没有, Duck和Airplane都没有实现你所谓的接口,但是都可以调用fly()方法,这难道不是面向接口编程, 如果你非要类比的话,这个fly就是一个自动化的接口啊。”

吉森确实没想到这一层,至于第二个原则,优先使用组合而不是继承,可以是每个面向对象的语言都可以实现的,他叹了口气,也就不问了。

Adapter模式

特使接着说:“Duck Typing非常强大,你不是提到了设计模式吗,在Duck Typing面前,很多设计模式纯属多此一举。我来给你举个例子,Adapter模式。假设客户端有这么一段代码,可以把一段日志写入文件当中。”

deflog(file,msg):

file.write( '[{}] - {}'.format(datetime.now(), msg))

“现在来了新的需求,要把日志写入数据库, 而数据库并没有write 方法,怎么办? 那就写个Adapter吧。”

classDBAdapter:

def__init__(self, db):

self.db = db

defwrite(self, msg):

self.db.insert(msg)

“注意这个DBAdapter并不需要实现什么接口(我大Python也没有接口),就是一个单独的类,只需要有个write方法就可以了。”

db_adapter = DBAdapter(db)

log(db_adapter, "sev1 error occurred")

确实是很简单,只要有write 方法, 不管你是任何对象,都可以进行调用, 典型的Duck Typing 。

既然Adapter可以这么写,那Proxy模式也是类似了,只要你的Proxy类和被代理的类的方法一样,那就可以被客户使用。

但是这种方法的弊端就是,不知道log方法的参数类型,想要重构可就难了。

单例模式

吉森又想到了一个问题,继续挑战特使:“Python连个private 关键字都没有,怎么隐藏一个类的构造函数,怎么去实现单例?”

特使不屑地说:“忘掉你那套Java思维吧,在Python中想写个singleton有很多办法,我给你展示一个比较Python的方式,用module的方式来实现。”

#singleton.py

classSingleton:

def__init__(self):

self.name = "i'm singleton"

instance = Singleton()

delSingleton # 把构造函数删除

使用Singleton:

importsingleton

print(singleton.instance.name) # i'm singleton

instance = Singleton() # NameError: name 'Singleton' is not defined

吉森确实没有想到这种写法,利用Python的module来实现信息的隐藏。

Visitor模式

不是每个设计模式都能这么干吧? 吉森心中暗想,他脑海中浮现了一个难于理解的模式:Visitor,自己当初为了学习它可是下了苦工。

吉森说:“那你说说,对于Visitor,怎么利用Python的特色?”

“我知道你心里想的是什么,无非就是想让我写一个类,然后在写个Visitor对它进行访问,是不是?”

classTreeNode:

def__init__(self, data):

self.data = data

self.left = None

self.right = None

defaccept(self, visitor):

ifself.left isnotNone:

self.left.accept(visitor)

visitor.visit(self)

ifself.right isnotNone:

self.right.accept(visitor)

classPrintVisitor:

defvisit(self,node):

print(node.data)

root = TreeNode( '1')

root.left = TreeNode( '2')

root.right = TreeNode( '3')

visitor = PrintVisitor()

root.accept(visitor) #输出2, 1, 3

吉森说:“是啊, 难道Visitor模式不是这么写的吗? ”

"我就说你的Python只是学了点皮毛吧,Visitor的本质是在分离结构和操作, 在Python中使用generator可以更加优雅地实现。”

classTreeNode:

def__iter__(self):

returnself.__generator()

def__generator(self):

ifself.left isnotNone:

yieldfromiter(self.left)

yieldfromself.data

ifself.right isnotNone:

yieldfromiter(self.right)

root = TreeNode( '1')

root.left = TreeNode( '2')

root.right = TreeNode( '3')

forele inroot:

print(ele)

不得不承认,这种方式使用起来更加简洁,同时达到了结构和操作进行分离的目的。

特使说道: “看到了吧,Python在语言层面对一些模式提供了支持,所以很多设计模式在我大Python看起来非常笨拙,我们这里并不提倡,当然我们还是要掌握面向对象设计的原则SOLID和设计模式的思想,发现变化并且封装变化,这样才能写出优雅的程序出来。”

吉森叹了一口气,感慨自己学艺不精,不再反抗,束手就擒。

尾声

Python王国审判了吉森,本来要判他死刑,但是Java帝国重兵压境,要求释放,否则就开战。

吉森被送回Java王国,成为了人们心目中的英雄,回家他仔细对比了Java和Python,在Java虚拟机上把Python语言给实现了!国王为了表彰他的英勇事迹,把这个语言叫做Jython。

ps. 本文故事受到了这个视频的启发:https://www.youtube.com/watch?v=G5OeYHCJuv0

●编号623,输入编号直达本文

责任编辑:

python用设计模式吗_为什么Python不用设计模式?相关推荐

  1. python创建模式对象_【python设计模式-创建型】单例模式

    单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一.这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式. 这种模式涉及到一个单一的类,该类负责创建自己的对 ...

  2. python面试设计模式问题_聊聊 Python 面试最常被问到的几种设计模式(下)

    1. 前言 上篇文章 写到了 Python 最常用的 2 种设计模式,单例模式和工厂模式 本篇文章我们继续聊聊面试中,Python 面试经常被问到的设计模式,即: 构建者模式 代理模式 观察者模式 2 ...

  3. python实现抢劵_用Python实现微信自动化抢红包,再也不用担心抢不到红包了

    1. 概述 刚刚收到了两个消息,一个好消息,一个坏消息. 先说好消息,好消息就是微信群里有人要发红包,开心~ 不过转念一想,前几次的红包一个都没抢到,这次???不由自主的叹了一口气 ... 过了一会, ...

  4. python黑科技脚本_利用Python实现FGO自动战斗脚本,再也不用爆肝啦~

    欢迎点击右上角关注小编,除了分享技术文章之外还有很多福利,私信学习资料可以领取包括不限于Python实战演练.PDF电子文档.面试集锦.学习资料等. 利用Python实现FGO自动战斗脚本,再也不用爆 ...

  5. python 运行程序代码_一些python程序

    <从问题到程序:用Python学编程和计算>--1.2 Python语言简介 本节书摘来自华章计算机<从问题到程序:用Python学编程和计算>一书中的第1章,第1.2节,作者 ...

  6. python大牛 关东升_《Python从小白到大牛》第4章 Python语法基础

    本章主要为大家介绍Python的一些语法,其中包括标识符.关键字.常量.变量.表达式.语句.注释.模块和包等内容. 标识符和关键字 任何一种计算机语言都离不开标识符和关键字,因此下面将详细介绍Pyth ...

  7. python库开源网站_开源Python库

    开源Python库 Python 一个很受人欢迎的原因之一是其有很丰富的第三方库,到本文开始写的时候已经在 PyPI 上有108298个第三方包提供.有人还对第三方库做了很好的总结 Awesome P ...

  8. python程序设计教材浅显易懂_这些python自学技巧,你不会?

    python自学,其实很简单. 其实python非常适合初学者入门.相比较其他不少主流编程语言,有更好的可读性,因此上手相对容易.自带的各种模块加上丰富的第三方模块,免去了很多"重复造轮子& ...

  9. python之禅 中文_《Python之禅》中对于Python编程过程中的一些建议

    <Python之禅>中对于Python编程过程中的一些建议 来源:中文源码网    浏览: 次    日期:2018年9月2日 [下载文档:  <Python之禅>中对于Pyt ...

最新文章

  1. (十二)企业级java springcloud b2bc商城系统开源源码二次开发-断路器监控(Hystrix Dashboard)...
  2. 安卓心理测试实训代码_我是如何从测试转到开发的
  3. 给公司员工上的培训1——微观规范
  4. php ajax城市联动,php+ajax 城市联动
  5. 使用DIV之后 table何去何从
  6. Bootstrap3 Affix插件
  7. java 栈和队列实现迷宫代码_使用两个队列实现一个栈
  8. vue如果 显示 如果 隐藏_隐藏在iPhone拨号键盘的4个秘密,如果你只用来打电话就太浪费了...
  9. UITableView 自带编辑删除 自己定义button
  10. linux mysql apache php 安装_linux下安装apache与php;Apache+PHP+MySQL配置攻略
  11. GitHub预测2018年开源项目趋势
  12. Win10禁用驱动程序强制签名方法
  13. 驰为 hi12 linux,驰为Hi12 最适合入手的手写平板 真的可以试试
  14. tar --exclude用法
  15. android 主流机型排行,安卓手机性能排行:华为Mate40 Pro仅排第四,第一名无可撼动...
  16. EasyUI学习笔记7:MIS开发利器_ datagrid插件(中)
  17. Pyyaml-yaml.load反序列化漏洞
  18. Fedora的服务详解zz
  19. CSRF---跨站请求伪造
  20. wps总是显示服务器错误,wps表格打开遇到错误的解决方法步骤

热门文章

  1. Xcode 模拟器路径
  2. AHK(1)之运行程序或打开文档
  3. 叮当猫商城系统开源的小程序商城系统
  4. CSS中有关定位的知识总结
  5. 联邦学习论文笔记——FedFair: Training Fair Models In Cross-Silo Fedrated Learning
  6. Vue中filter清空数组的空值,在computed处理
  7. 连接向导中的拨号调制解调器或 PPPoE 选项不可用问题
  8. 产品经理学习网站和工具
  9. [导入]php编码规范
  10. 什么是关心?什么是理解?