从面向对象的设计模式看软件设计
前些天发了一篇《如此理解面向对象编程》的文章,然后引起了大家的热议。然后我在微博上说了一句——“那23个经典的设计模式和OO半毛钱关系没有,只不过人家用OO来实现罢了……OO的设计模式思想和Unix的设计思想基本没什么差别”,结果引来了一点点争议。所以,我写下这篇文章把我的观点说明一下。我希望这样可以让大家更容易地理解什么是设计模式。我顺便帮OO和 Unix/Linux搞搞基。
目录
什么是模式
在正式说明GoF的那23个经典的设计模式其实和OO关系不大并和Unix的设计思想很相似的这个观点之前,让我先来说说什么是模式?设计模式的英文是Design Pattern,模式是Pattern的汉译。所谓Pattern就是一种规则,或是一种模型,或是一种习惯。Pattern这个东西到处都是,并不只有技术圏子里才有。比如:
- 文章有文章的Pattern。如新闻有新闻的Pattern(第一段话简述了整个新闻),诗歌总是抒情的,论文总是死板的,讲稿总是高谈的,漫画总是幽默的,……
- 小说有小说的Pattern。比如,
- 武侠小说必然要整个武林大会,整几个NB的武功和大师,分个正派和反派,还有一个或数个惊天阴谋,坏人总是要在一开始占尽优势,好人总是要力挽狂澜……
- 言情小说总是要有第三者,总是要有负心人,里面的女子总是要哭得死去活来,但又痴心不改,……
- 新闻联播的模式是:头10分钟领导很忙,中间10分钟人民很幸福,后10分钟国外很乱。中国政府官方宣传稿也模式也很明显,各种赞美,口号,胜利,总是要坚持个什么,团结个什么,迈向个什么,某某精神,某某思想,群众情绪稳定,不明真相,等等……
- 春节的模式是,回家,吃饺子,放个鞭炮,给压岁钱,同学聚会…… 同学聚会的模式基本上都是在饭桌上回忆一下校园时光,比较一下各自的当前处境,调戏一下女同学……
- …… ……
这就是Pattern,只要你细心观察,你会发现这世间有很多很多的Pattern。
GoF的23个设计模式
《设计模式》这本书中,GoF这四个人总结了23个经典的面向对象的设计模式,某中有5个创建模式,7个结构模式,11个行为模式。很多人都会觉得这是面向对象的设计模式,很多人也觉得非面向对象不能用这些模式。我觉得这是一种教条主义。就像《那些流行的编程方法》中的“设计模式驱动型编程”一样,就像《如此理解面向对象》一样的那么的滑稽。
好了,回到我的论点——“GoF的这23个设计模式和OO关系不大,并且和Unix的设计思想基本一致,只不过GoF用OO实现了它们”,就像我上面说过的那些生活中的Pattern一样,只要你仔细思考,你会发现这23个设计模式在我们的生活和社会中也能有他们的身影。而且也一样可以用OO的方式实现之。
让我们来看看这23个经典的设计模式中的几个常用的模式:
Factory 模式,这个模式可能是是个人都知道的模式。这个模式在现实社会中就像各种工厂一样,工厂跨界的不多,基本上都是在生产同一类的产品,有的生产汽车,有的生产电视,有的生产衣服,有的生产卫生纸……基本上来说,一个生产线上只有做同一类的东西。这和Factory模式很相似。编程中,像内存池,线程池,连接池等池化技术都是这个模式,当然,Factory给你的一个对象,而不单单只是资源,factory创建出来的对象都有同样的接口可以被多态调用。这其实和Unix把所有的硬件都factory成文件一样,并提供了read/write等文件操作来让你操作任意设备的I/O。
Abstract Factory:抽象工厂这个模式是创建一组有同一主题的不同的类。这个模式在现实社会当中也有很多例子,比如:
- 移动公司的合约机计划,88套餐(通话100分钟,短信100条,彩信,20条,上网200M),128套餐(通话200分钟,短信150条,彩信50条,上网500M)……
- 家里的装修,总是要有厨卫,有门,有灯,有沙发,有茶几,有床,有衣柜,有电视,有冰箱,有洗衣机……,这些都是必需的,只是每个家庭里的具体装修不一样。
- Diablo游戏中的Normal,Hard,Nightmare,Hell模式,这些模式的怪和场景和故事情况都差不多,就是每个场景的怪物和装备的属性不一样。或是WarCraft中的地图就是一个Abstract Factory模式(注:Warcraft的地图什么都能干)。这和学校中的小学,初中,高中,大学差不多,都是一样的学习环境,一样的教学方式,一样的教室,都要期中考和期末考,都有班长和科代表,就是学的东西的难度不一样,但基本上都是语文,英语,数,理,化,还有永远都有的政治课。学校就是一个抽象工厂。
这就是抽象工厂的业务模型(或是:Business Pattern),你觉得是不是不一定非要用OO来实现这样的模式?(我们思考一下,我们会不会被先入为主了,觉得不会OO都不知道怎么实现了),不用OO,用相同格式但内容不同的配置文件是不是也能实现?在Unix下,抽象工厂这个模式在Unix下就像是/etc/rcX.d下的那些东西,1代表命令行单用户,2,代表命令行多用户,3代表命令行多用户完整模式启动,5代表图形界面启动,0代表关机,6代表重启,你要切换的话,init <X>就行了。
Prototype模式,原型模式,复制一个类的实现。这个模式在现实中的例子也有很多:传真,复印,都是这个模式。Unix进程和Github项目的Fork就是一种。进程fork明显不是OO的模型(参看:关于Fork的一道面试题)。用非OO的方法同样可以实现这个模式。
Singleton模式,单例模式。生活中,公司只有一个CEO,法律限制你只能有一个老婆,你只能有一个身份证号,一个TCP端口只能被一个进程使用,等等。软件开发方面,并不一定只有OO才能做到,你可以用一个全局变量,一个中心服务器,甚至可以使用行政手段来约束开发中不会出现多个实例。Unix下实现单例进程的一个最常用的实践是在进程启动的时候用“(S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)”模式打开一个“锁文件”。
Adapter模式,适配器模式。可以兼容欧洲美国中国的插头或插座,万能读卡器,可以播放各种格式多媒体文件的插放器,可以解析FTP/HTTP/HTTPS/等网络协议的浏览器,可以兼容各大银行的银联接口、支付宝、Paypal、VISA等银行接口,可以适配各种后端的解释器的Nginx或Apache,等等。用非OO的编程方式就是重新包装成一个标准接口。这个模式很像Unix下的/dev下的那些文件,操作系统把系统设备适配成文件,于是你就可以使用read/write来进行读写了。
Bridge模式,桥接模式。这个模式用的更多,比如一个灯具可以接各种灯泡或灯管,一个电钻可以换上不同的钻头来适应不同的材料,一辆汽车可以随时更换不同的轮胎来适应不同的路面,你的桌面可以随时更换一个图片来适应你的心情,你的单反相机可以更换不同的镜头来拍不同的照片…… 桥接模式说白了就是组件化,模块化,可以自由拼装。在OO中,其主要是通过让业务类组合一个标准接口来完成,这在非OO的程序设计中用得实在是太多了,主要是通过回调函数或是标准接口来实现。这个也是Unix设计哲学中的主要思想。在Unix中,文件的权限使用的就是Bridge模式,标准接口是用户,用户组和其它,rwx三个模式,然后用 chmod/chown改一改,这文件就有不同的属主和属性了。
Decorator模式,装饰模式。这个模式在生活中太多了,你给你的手机或电脑贴个什么,挂个什么,吃东西的时候加点什么佐料,多点肉还是多个蛋,一个Unix/Linux命令的各种参数是对这个命令的修饰,等等。我觉得这个模式在Unix中最经常的体现就是通过管道把命令连接起来来完成一个功能,比如:ps -elf 是列进程的,用管道 grep hchen就可以达到过滤的目的,grep的逻辑没有侵入ps中,grep 修饰了 ps,但是其组合起来完成了一个特定的功能。可见,这和OO没有什么关系。
Facade模式,这个模式我们每个人从会编程的时候就在无意识地用这个模式了。这个模式就是把一大堆类拼装起来,并统一往外提供提口。在现实生活中这样的例子太多了,比如:旅行社把机票,酒店,景点,导游,司机,进店打了一个包叫旅行;IBM把主机,存储,OS,J2EE,DB,网络,流程打了个包叫企业级解决方案。Unix中最典型的一个例子就是用Shell脚本组合各种命令来创造一个新的功能,这是的Shell中的各种命令通过标准I/O这个接口进行组合交互。
Proxy模式,代理模式。我们租个房,买个机票,打个官司,都少不了代理,人大代表代理了老百姓去行使政治权力。我们去饭馆里吃饭也是一种代理模式,因为我们只管吃就好了,洗菜做饭洗碗的工作都被Proxy帮你干了,于是你就省事多了。操作系统就是硬件的代理,CDN就是网站的代理,……使用代理你可以让事情变理更简单,也可以在代理层加入一些权限检查,这样可以让业务模块更关注业务,而把一些非业务的事情剥离出来交给代理以完成解耦。可见这个模式和OO没啥关系。Unix下这个模式最佳体现就是Shell,它代理了系统调用并提供UI。还有很多命令会帮你把/proc目录下的那些文件内容整理和显示出来。
Chain of Responsibility模式,劫匪来抢银行,保安搞不定,就交给110,110搞不定就交给武警。有什么事件发生时的响应的Escalation Path,办公中的逐级审批。这个模式用一个函数指针数组或是栈结构就可以实现了。这个思想很像编程中的异常处理机制,一层一层地往上传递异常直到异常被捕捉。在Unix下,一个最简单的例子就是用 && 或 || 来把命令拼起来,如:cmd1 && cmd2 或 cmd3 || cmd4 , 如果cmd1失败了,cmd2就不会执行,如果cmd3失败了,cmd4才会执行。如: cd lib && rm -rf .o 或 ping -c1 coolshell.cn && ssh [email protected]
Command模式,这恐怕是软件里最多的模式了,比如:编译器里的Undo/Redo,宏录制。还有数据库的事务处理,线程池,设置向导,包括程序并行执行的指令集等等。这个模式主要是把一个对象的行为封装成一个一个的有相同接口的command,然后交给一个统一的命令执行器执行或管理这些命令。这个模式和我们的Unix/Linux机器启动时在/etc/init.d下的那些S和K开头的脚本很像,把各种daemon的启动和退出行为封装成一个脚本其支持reload/start/stop/status这样的命令,然后把他们按一定的规范做符号链接到/etc/init.d目录下,这样操作系统就会接管这些daemon的启动和退出。
Observer模式,观察者模式,这个模式也叫pub-sub模式,很像我们用手机订阅手机报,微博的follow的信息流也是这样的一个模式。MVC中的C会sub V中的事件,用非OO的方式其实也是一个回调函数的事。在很多异步系统中,你需要知道最终的调用有没有成功,比如说调用支付宝的支付接口,你需要向支付宝注册一个回调的接口,以便支付宝回调你。Linux下的一些系统调用如epoll/aio/inotify/signal都是这种思路。
Strategy 模式,策略模式,这个模式和Bridge模式很像,只不过Bridge是结构模式,其主要是用于对象的构造;而Strategy是行为模式,主要是用于对象的行为。策略模式很像浏览器里的各种插件,只要你装了某个插件,你就有某个功能。你可以安装多个插件来让你的浏览器有更多的功能(书本上的这个模式是你只能选用一个算法,当然,我们不用那么教条)。就像《你可能不知道的Shell》中的那个设置设置$EDITOR变量后可以按ctrl+x e启动编译器,或是用set -o vi或set -o emacs 来让自己的shell像vi或 emacs 一样,或是像find -exec或xargs一样的拼装命令。
Bridge 和 Strategy是OO设计模式里的“Favor Composition Over Inheritance” 的典范,其实现了接口与实现分离的。Unix中的Shell就是一种,你可随意地更换不同的Shell。还有Emacs中的LISP驱动C,C实现了引擎,交给LISP实现逻辑。把程序分为前端和后端,通过socket专用应用协议进行通讯,前端实现策略,后端实现机制。再看看makefile把编译器和源代码的解耦,命令行输出这个接口可以把一个复杂的功能解耦并抽像成各种各样小而美的小功能命令,等等这样的例子,你会发现,还有大量的编程框架都会多少采用这样的思想,可以让你的软件像更换汽车零件一样方便。我在用Unix的设计思想来应对变更的需求中说过灯具厂,灯泡厂,和开关厂的例子。
后记
因为写作仓促,上面的那些东西,可能会你让你觉得有些牵强,那么抱歉了,你可以帮我看看在生活中和 Unix里有没有更帅的例子。
不过,我们会发现上面OO搞出来的那么多模式在Unix下看来好像没有那么复杂,而且Unix下看起来并没有那么多模式,而且Unix中的设计模式无非就是这么几个关键词:单一,简洁,模块,拼装。我们再来看看OO设计的两大准则:1)钟情于组合而不是继承,2)依赖于接口而不是实现。还有S.O.L.I.D原则也一样(如果你仔细观察,你会发现SOLID原则在Unix下也是完美地体现)。你看,Unix和OO设计模式是不是完美的统一吗?
我有种强烈的感觉——Unix对这些所谓的OO的设计模式实现得更好。因为Unix就一条设计模式!再次推荐《The Art of Unix Programming》
餐后甜点
我上面提到了《The Art of Unix Programming》,所以我有必要再谈谈这本书中我中毒最深的一章《模块性:保持清晰和简洁》中所谈到的胶合层。
胶合层这一节中说了,我们开发软件一般要么Top-Down,要么Bottom-Up,这两种方法都有好有不好。顶层一般是应用逻辑层,底层一般是原语层(我理解为技术沉淀层,或是技术基础层)。自顶向下的开发,你可能会因为开发到底层后发现底层可沉淀的东西越来越不爽(因为被可能被很多业务逻辑所侵入),如果自底向上的开发,你可能越到上层你越发现很多你下面干的基础上工作有很多用不上(比如干多了)。所以,最好的方式是同时进行,一会顶层,一会底层,来来回回的开发——说白了就是在开发中不断的重构,边开发边理解边沉淀。
无论怎么样,你会发现需要一层胶合层来胶合业务逻辑层和底层原语层(软件开发中的业务层和技术层的胶合),Unix的设计哲学认为,这层胶合层应该尽量地薄,胶合层越多,我们就只能在其中苦苦挣扎。
其实,胶合层原则就是分离原则上更为上层地体现,策略(业务逻辑)和机制(基础技术或原语)的清楚的分离。你可以看到,OO和Unix都是在做这样的分离。但是需要注意到的时,OO用抽象接口来做这个分离——很多OO的模式中,抽象层太多了,导致胶合层太过于复杂了,也就是说,OO鼓励了——“厚重地胶合和复杂层次”,反而增加了程序的复杂度(这种情况在恶化中)。而Unix采用的是薄的胶合层,薄地相当的优雅。(通过这段话的描述,我相信你会明白了《如此理解面向对象编程》中的个例子——为什么用OO来实现会比用非OO来实现更为地恶心——那就是因为OO胶合层太复杂了)
OO的最大的问题就——接口复杂度太高,胶合层太多!(注:Unix编程艺术这本书里说了软件有三个复杂度:代码量、接口、实现,这三个东西构成了我们的软件复杂度)
再送一个果盘
大家一定记得《SteveY对Amazon和Google平台的长篇大论》中Amazon中那个令人非常向往的SOA式的架构。因为以前在Amazon,有些话不好说。现在可以说了,我在Amazon里,我个人对这个服务化的架构相当的不待见,太复杂,复杂以乱七八糟,方向是好的,想法也是好的,但是这东西和OO一样,造成大量的接口复杂度,今天的Amazon,完全没人知道各个服务是怎么个调用的,一团乱麻(其内部并不像你看到的AWS那么的美妙。注:AWS是非常不错的,是相当好的设计)。
那么我们怎么来解决SOA的接口复杂度问题?其实,Unix早就给出了答案——数据驱动编程(详见:《Unix编程艺术》的第9.1章),在我离开Amazon的时候,美国总部的Principle SDE们在吐槽今天Amazon的SOA架构,更好的架构应该是数据驱动式的。(今天还在Amazon的同学可以上内网boardcast上看看相关的Principle Talk视频)
(瞎扯一句:这本来是我想在2012年杭州QCon上的分享的一个主题,无奈当时被大会组织者给拒了,所以只好讲了一个《建一支小团队》,今天有多人还是不能明白甚至反感我的那个《小团队》的演讲,但是我相信那是必然的趋势,就像十年前大家在说“程序员只能干到30岁”时,当时的我我却毫不犹豫地相信十年后,30岁以上的有经验的老程序员一定会成为各个公司角逐和竟争的红人)
(转载本站文章请注明作者和出处 酷 壳 – CoolShell ,请勿用于任何商业用途)
《从面向对象的设计模式看软件设计》的相关评论
“Proxy模式,原型模式,复制一个类的实现。” Typo?
找到笔误一处:
“Proxy模式,原型模式”
请确认谢谢
第一个出现proxy的地方应该是prototype.
个人认为 Bridge模式,桥接模式 的比喻不太恰当。该模式应该是通过接口将两个各自独立的体系不同的事物链接起来。例如主板跟显卡 通过 显卡插座连接,用户可以用不同牌子的主板,显卡。主板和显卡各自有自己的产品体系。前提只要两者遵从相同接口。该模式中,接口就好比连通两者的桥梁,所以叫桥(接)模式。
个人意见,欢迎讨论。
那句”那23个经典的设计模式和OO半毛钱关系没有,只不过人家用OO来实现罢了……OO的设计模式思想和Unix的设计思想基本没什么差别”,前半句最然很激进,但基本含义我同意,后半句有点牵强.文章中阐述了很多模式在Unix中的例子,可这只是模式在Unix中的应用,并不能论证“OO的设计模式思想和Unix的设计思想基本没什么差别”,而是进一步论证了前半句。
终于更新了。
30岁现在已经不算老程序员了,趋势还是有改变的~~~
“Chain of Responsibility模式” 一节说 “在Unix下,一个最简单的例子就是用 && 来把命令拼起来,如:cmd1 && cmd2 &&, 如果cmd1失改了,cmd2就会执行,如果cmd1和cmd2都失败了,cmd3才会执行。”
&&似乎在前者成功后才会运行后者,“||”才是在前者失败的情况下运行后者。。。
cd lib && rm -rf .o 或 ping -c1 coolshell.cn && ssh [email protected]
这两个例子应该是第一个命令成功之后再执行第二吧,应该用 || ?
cmd1 && cmd2 &&, 如果cmd1失改了,cmd2就会执行,如果cmd1和cmd2都失败了,cmd3才会执行。
一个文字错误,外加逻辑错误。cmd1失败 了cmd2就不会执行,cmd3只有在前两个都成功后才执行。
是的,对不起,是我写错了。
> Proxy模式,原型模式,复制一个类的实现。
Proxy应该改为prototype吧
OO的最大的问题就——接口复杂度太高!
太认同这句话了!
好文章,非常期待能把其他的12个模式也用这种生动的比喻写出来。赞!
导致OO接口复杂度过高不是因为OO,而是因为人,随意下这个定义不太好吧。
不错,我一直也想写篇文章,介绍开源软件中的设计模式(C语言实现)~
很多新概念还不是很熟悉,就抓几个语文的问题吧:
“我随便帮OO和 Unix/Linux搞搞基。”
-> 随便 是不是 “顺便”?
“你看,Unix和OO设计模式是不是完美的统一吗?”
-> 这个有点疑问句和反问句混合了的样子,觉得下面这样可能会更通顺:
疑问句:你看,Unix和OO设计模式是不是完美的统一了(呢)?
反问句:你看,Unix和OO设计模式不是完美的统一了吗?
这个例子举得很好啊,硬件里面的接口设计历史其实远比软件行业来得早啊~~~@郭文君
老程序员的前景,还是取决于项目、系统是靠关系得来还是靠技术。
模式是思想,OO是实现手段,同样的思想可以用N中手段实现
If u cant explain simply u dodt understand it well enough.
这个理解的太牵强了。OO和Unix设计思想的基情好比 FP和菜布尼茨的基情一样。这基情实在太浅了!
亚里士多德,“分类学”(Category),这些东西老早就有的东西。
“设计模式”也当然不是OO的专利。
所谓“OO”,所谓“面向对象”,这里重要的不是“对象”,分类学都不知道出现了老长时间了。将世界理解成对象组合,分类,类型的,这种思想在生活中到处可见。
不是“设计模式”与Unix设计思想有什么参照或基情的关系。而是他们都是基于这一简单的分类学理论。
另外,看了一些评论对OO的看法。我想强调,“面向对象”,更重要是“面向”。
在一种简单哲学看来,世界本来就是对象的。而在程序设计中,重要的是要把握“面向”这一点。
设计模式应该是源于建筑行业,是对前人施工、构筑的总结;如何才能高效、高质量的完成施工任务。软件开发也要走向高效、稳定、可预见,所以引入了模式;可以像建筑行业一样能预见一个需求多长能够彻底完工。软件开发的不确定性往往取决于程序人员对电子计算机的了解;了解越多开发、施工的速度越快;工期也越能预见准确。所以只有更深入的了解计算机的运行实质、编程语言的细节才能高效、优质、可预见性的完成开发项目。
设计模式,没有说是软件设计模式,是通用的模式,规范,告诉大家如果做事按照这个规范做将是高效、稳定、可预见性的。所以我认为,是OO计算机行业对设计模式的高效支持,而设计模式则是自然法则。
我认为的OO按目的来分有两种:
1,以领域建模为目的的OO
2,以工程上的便利性(封装、重用、解耦、契约、)为目的的OO
其中2并非OO独有的,我相信所有出于目的2中的OO都可以用等价的非OO实现来替换之。因此,凡是不以建模为目的的OO都是不必要的。
+12306
事物的分类本来就是随心所欲的。比如,你所理解的资产/负债,和理财理论里面的就完全不是一码事。
这可能也是理工宅和文科傻怎么都玩不到一块的一个原因:双方甚至对什么是“好”、什么是“优雅”的理解都有根本差异!
写软件也一样。你说如果有谁连要做什么、怎么做都一无所知,就跑一边自顾自的把“类”分了——你说这人是真傻呢,还是真傻透了呢?
——为何《如此理解面向对象编程》如此搞笑?因为……我们虽然知道真傻透了的家伙很傻……但没想到他能傻成那样!
面向对象编程,哈哈,是不是先得有个对象哈!
這麼說,面向對象還有什麽用???
非常脑残
如果我说电风扇和电半毛关系也没有,因为不能利用电能的古代人就会用蒲扇了,站在马路上一阵风吹来我也很凉快,电风扇不过是用产生风的一种手段而已。所以我说电风扇和电没关系,多半人都会喷我。但是说23种模式和OO没关系,COMMON SENSE很差的笨蛋就会点头了
在提到23种设计模式的时候就已经是在说OO领域的模式了,好理解么?
23种模式你能一一对应到现实生活中的例子么,能作为其他领域的模式么?
发表脑残言论活该被批
看到一处笔误,不过之前有人说了
第三个原型模式 英文写错了,抽象工厂下面
皓哥。你的博客,搜索功能很鸡肋耶。我搜个google没反应
一直不懂所谓的OO的模式,所以面向对象都么学
unix编程艺术是本好书
我靠,
这下子尴尬死了,我想写个“我靠!都皓子哥的技术文章也能笑着读,前面的幽默真的很幽默(我承认这是废话)”,写了“我靠”两个字一步小心点了回车就尴尬了,这真是很尴尬,看来这个读blog留言评论的Pattern也得总结一下子,想幽默一下子,一不小心就会弄巧成拙
首先麻烦皓哥改个笔误:后记里“你会发现SOLID原则在Unix下也是完美地体美”(体现)。。。关于OO胶合层太厚有个问题就是你根本不知道某个胶合层的时间复杂度和CPU使用率。。。。。所以我有时候还得自己重新写一遍接近底层的代码。。。
现在的工作主要侧重于LINUX后台,对这些设计模式越来越生疏了。。。
到处都有欢乐的吐槽
把设计模式与面向对象等串起来梳理一番是件好事,可是总感觉有些别扭的…也不够优雅 哈哈…或许是我功力不够,理解不透彻……
非常赞同!设计思想重要的是思想,如何实现按需而定。
还有常用的Private Data模式。
不同的人会有不同的感受,站在不同的高度看到的风景是不同的。
我的理解是:
设计模式是解决软件开发中的一些问题的手段,比如它们是前人为了解决 代码扩展性不佳,代码可复用度不高,代码重复度过大之类问题而总结出来的方法。 但方法终究是方法, 它必须是伴随问题而存在的。 方法背后的思维方式才是最重要的。
陈皓的主张也是希望大家多去关注设计模式背后的思想,他认为这个思想本质上是与《The Art of Unix Programming》中提倡的思路是一脉相承的。 设计模式无非是这种思想的一种实现而已。
整篇文章很牵强。整个unix只有命令模式和责任链,勉强说得过去。Gof的设计模式是特定针对程序员编码的,不是说shell的使用,unix的日常管理的!
如果说“模式”或者“设计模式”,那肯定任何语言,任何平台都有自己的模式。但是如果特指Gof的23种设计模式,那真的是面向对象的领域,非扯到unix太牵强了。 我不是说unix就没有模式,没有设计模式;我的意思是:gof的32种和unix的管理日常使用,完全是两个宇宙的东西。你真要比较你应该比较OO语言和shell,或者oo语言和c语言。
你连第一个都没说到点子上,Factory模式是因为:面向对象的时候,很多对象要new。复杂的类或者对象,在不同的情况下构造出来,那么可能会导致多个不同的构造函数,这样写出来的代码比较“反模式”不适合别的程序员阅读,所以可以单独写一个工厂类(Factory)这样,代码分离了,比较好看。
你举例Bridge 和 Strategy模式,你根本没谈到编码,完全是在说shell的使用方法。完全不是同一个领域的东西。
所以
我最后强调一点:Gof的23种模式,不是说为了实现某一个功能要这样做。你不遵守这些模式,用“反模式”的方法一样绝对也能实现你的需求。哪怕是OO的语言,你不用工厂,不用装饰模式,你的代码照样也能工作。Gof的23种模式的目的,是为了代码能够更好看,更能被人阅读!
我补充一下: 我的理解,unix的设计思想是“一切都是文件”和“流”的思想。
你当然可以说,文件就是OO里面的对象,流就是OO里面的api。
如果这么抽象,那么C语言也有OO,对象不过是一个结构体而已。那么汇编语言也能和C语言一样。那么,就根本不必发明出这么多的语言,全部用机器码全部用汇编得了。
Gof里面开篇就说了,这是面向对象的研究。当然里面的某些模式,有可能会被非面向对象的语言用到。现在谈模式的书,有分析模式,有并发模式,有函数编程模式,SOA模式,各种各样的模式。Gof的23种模式,毫无意义是指面向对象的。
还有一点,我最最强调的是:Gof的模式也好,函数编程模式,并发模式也好;目的是为了让编程的代码更可读,复用性能更高。如果你完全不用任何模式,“反模式”在某些情况下也是一种选择;你一样也能实现出同样功能。只是,你的代码不可读,不可维护而已。
coolshell越来越有弯曲评论的范了~~
其实,我相信设计模式和OO无关,也和语言无关。
由于我本身是现在只学习了java,对c不了解。先生能否用C实现一次23种模式?
还有一个观点:设计模式的出现说明的是语言本身的不足?不知道先生有何理解?
OO关键在于封装。说白了就是定义明确的访问控制。对象粒度控制很广泛。而linux的隔离级别的单位却是进程,很重的资源。你非要说我可以通过某种访问协议访问细粒度的资源。其实这行为本身就变成了一种丑陋的OO。
瞎扯一句:这本来是我想在2012年杭州QCon上的分享的一个主题,无奈当时被大会组织者给拒了,所以只好讲了一个《建一支小团队》
———-
是拒了还是选了一个更会引起争鸣的话题呀? 当时我怎么什么都不知道。 今年再来讲个?:)
学习啦!虽然有些观点不完全赞同
Diablo没有Hard模式,有其余三种模式