关于设计模式

2019-09-08 16:55:28 +08:00
 Kontinue

看到一些讲设计模式的书或博客,一般都会列出模式的定义,对应 UML 图和基本实现。

想知道,模式这种东西,是否就一定要按照标准 UML 图画的那样去实现?还是说只要把握到具体模式的意思,而具体实现的形式可能就未必要和 UML 图一致。

就比如说,适配器模式,在用的时候,一定要有 Target、Adaper、Adapee 吗?

不知道能不能 get 我想问的。。。

3179 次点击
所在节点    程序员
14 条回复
shylockhg
2019-09-08 17:07:58 +08:00
参考张无忌学太极拳太极剑
lovedebug
2019-09-08 17:11:16 +08:00
设计模式最好跟你所用的语言编程模型相匹配。
另外联系现实中实体例子就知道需要哪些角色了
guyeu
2019-09-08 18:40:23 +08:00
不一定严格按照设计模式的 UML 图来进行实现,实际上设计模式在带来某种套路化的便利的同时,也会引入一些问题。(有些设计模式在遵循了某个规范的时候,也会打破另一个规范)理解设计模式的几个原则,在编码的时候取舍,就可以了。

学过设计模式之后,最需要注意的是不要“过度设计”。
joyhub2140
2019-09-08 18:47:27 +08:00
设计模式是多种 OOP 设计原则的集合体,本身强调的是设计思维,不需要严格按照书本所说的范式去实现,还有可能会根据场景做相应变种,但总体实现不会变动太大。
Takamine
2019-09-08 19:47:12 +08:00
我更倾向是一种抽象思维,而且不要拘泥在用哪个上面。
做到代码复用,解耦,好扩展就好。
holy_sin
2019-09-08 19:51:10 +08:00
代码符合开闭原则就是好的设计模式,浅见
Leigg
2019-09-08 20:08:03 +08:00
当然不必了,但是你要确定你若实现的设计没有瑕疵漏洞,毕竟现有的设计模式是经过前人大量实践总结出来的,你懂我意思吧?所以最好你先使用现有的设计模式,你觉得哪里可以精简或者改善再去斟酌。
c0011
2019-09-08 21:05:31 +08:00
《 head first 设计模式》
Kontinue
2019-09-08 21:17:48 +08:00
@c0011 现在再看这本书感觉太口水了
Xbluer
2019-09-08 21:25:03 +08:00
如果你确定需要使用到某一种设计模式,那直接套用就好了,毕竟设计模式就是一系列经典问题的通用解决方案。甚至可以更教条一点,可以在类名中直接使用对应的关键词,比如构建者模式(XxxxBuilder)、观察者模式(Observer,Subject)以及你提到的适配器模式(Adaper)。如此,后来接手的人也能快速识别出对应的设计模式。

但真正的难点在于如何在业务逻辑中识别出这些经典的问题,同时还要权衡是否有必要使用对应的设计模式。一般来说,代码实现套用了设计模式代码会变得更复杂一些,但是可以更加适应业务需求的变更。

一点个人看法。。。
FrankHB
2019-09-08 21:31:01 +08:00
所谓的设计模式就是因为解决的问题(如果有的话)过于局部而没资格作为架构模式复用又没法作为惯用法的鸡肋。

跟很多初学者想象的相反,绝大多数所谓的设计模式跟设计没什么直接的关系,而更接近要成为惯用法却因为语言设计的局限性(例如缺乏一等函数)而失败的半吊子,因此实际上也没用于解决什么设计上的问题,反倒因为模糊问题领域而造成误导。
只有少数周知的设计模式是例外,例如 MVC 可以认为是半个架构模式。剩下的设计模式只能认为是解决了设计的某些表达困难这种实现上的问题。
典型地,一些所谓的创建型模式,就是因为创建对象的语言特性过于特殊(构造器是函数却具有普通的函数以外的特殊规则),根本不方便复用而发明的变通。例如,C++17 引入 deduction guide 以后,所谓的 make_xxx 这样的模板方法就没多大实用性了。(虽然 deduction guide 自身有混淆 higher-order type 堵死类型系统可扩展性和无法抽象复用 helper function 的更严重的问题。)

设计模式受制于范型(paradigm) 。大多数设计模式都只适用于支持面向对象设计的语言。相比,架构模式通常不依赖范型,而惯用法则同时依赖泛型和语言。
注意,偏向于架构模式还是惯用法并不蕴含解决更多或更少的设计方面的问题,只是表达和具体语言依赖的紧密程度的差异。RAII 作为惯用法,解决的问题比大多数设计模式要“设计”得多。

虽然设计模式通常不依赖个别的具体语言,但因为范型的影响,可能受制于一类语言的设计。有些设计模式可能一开始就是语言的设计者灌输的并且强烈依赖语言特性提供可用性,例如所谓纯函数式语言常见的单子(monad) 模式,配合语法糖作为可模拟顺序求值作为惯用法。

至于所谓的的 UML 是给建模用的,表达的本来倒的确是设计,然而因为历史原因方法论上非常有局限性,基本只能面向对象,不能适应其它范型的实现。
UML 跟各种意义的模式本来就没什么关系,只是一开始搞的设计模式都是面向对象的模式,才恰巧能用得上。
用到了 UML 表达的模式和使用代码表达模式的例子相比看上去是提升了抽象层次,实际只是强烈暗示看起来不像是平凡的惯用法而已,结果反而容易弱化模式的外延而显得不准确(例如,误认为创建型模式一定需要用到类)。这是因为根本上 UML 的表达能力还不如通常的编程语言。
因此,照着 UML 这样弱的语言去套用模式,基本上是不理解模式的。

不少设计模式的发明者本身不理解他们所使用模式的名称的内涵。例如,提出解释器模式的,看上去就根本没写过一个 REPL,以至于抓不住解释器提供的是面向 IR (排除包括语法在内的任何典型的文法分析)的翻译而不是对所谓的“表达式”求值(包含语法分析)的核心本质。
考虑到很多设计模式除了名字以外就没什么值得记忆的地方(例如你会用 singleton 还不如搞清楚和 monostate 的区别),设计模式中有用的部分,就是拿来即兴发明而不是取名的。照着具体组成的名字骑驴找马,不仅本质上是反模式的学习方式,可以说还是“反方法论”的。

(看起来 v2 也得像贴吧一样加个 FAQ 清单么……)
charlie21
2019-09-08 22:31:10 +08:00
wd
2019-09-09 04:53:35 +08:00
设计模式是别人总结出来解决一类问题比较好的思路,你自己根据你的实际情况灵活变通当然可以
c0011
2019-09-09 08:43:17 +08:00
@Kontinue 感觉看完不应该问这样的问题啊

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/599048

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX