不要因为你不用这本书就讨厌它

2020-09-19 17:32:24

再过几个月,我将庆祝我作为一名专业的付费软件工程师的第五个年头。我发现这个角色恰到好处地平衡了技术技能和人际关系,它满足了我的好奇心。随着时间的推移,我也开始对它的一些消极方面感到失望。虽然它不会阻止我睡觉,但我认为可以努力挑战我们每天在社交平台上看到的一些糟糕和短视的评论。

今天,我想谈谈Erich Gamma、Richard Helm、Ralph Johnson和John Vlisside写的书“设计模式:可重用面向对象软件的元素”,该书被称为“四人帮”。如果您从未读过:这是一本描述编程抽象的基础编程书籍,出版于1994年。日期在这里很重要,但我们稍后再谈。

由于罗伯特最近的一条推文,这本书最近受到了许多人的讨论。C.马丁,也就是鲍勃叔叔。长话短说,告诉广大观众X书很棒,认为它过时的人“愚蠢”不会有好下场。

虽然我不同意这里的基调,但我想重点谈谈随之而来的负面评论,包括但不限于:

首先让我们回到1994年。当时我才两岁。所有的互联网网站可能都可以放在一张软盘上,杰夫·贝佐斯创立了亚马逊,Rasmus Lerdorf才刚刚开始开发其个人主页/表格解释器CGI C程序,拉里·佩奇和谢尔盖·布林两年后才开始他们的网络搜索引擎研究项目。最大的科技公司是IBM、惠普(Hewlett-Packard)、摩托罗拉(Motorola)和施乐(Xerox),它们大多落后于石油、汽车和食品行业。编程是存在的,但它与我们今天所知的领域不同。科技公司为数不多,我想很多程序员都在其他行业工作。当时,作为这一领域的专业人士可以说更加困难,知识也不像今天那么容易获得。这本书是在编程开始在许多行业传播的世界里出版的。这当然是一个非常好的资源,可以尝试应用它的概念,看看哪些有效,哪些无效。作者当时确实在发明这个领域:例如,Erich Gamma在几年后与Kent Beck合作创建了Java JUnit测试框架,这极大地帮助了测试的普及。

我的观点是:让我们提醒自己,我们站在许多人的肩膀上,他们在当时进行了大量的尝试和试验。我们常常认为我们今天拥有的知识和生产力是理所当然的。最重要的是,我们不要对上一代人不敬。我父亲和我祖父都是电工:我父亲以前从来没有抱怨过他父亲的工具或习惯。他学习了它们,并用现代知识完善了它们。

现在谈谈这本书本身。虽然我同意有人说一些设计模式太抽象,但我强烈反对说整本书都过时了。如果您今天使用面向对象语言(如Java、C++、Python或Ruby)进行开发,或者更值得注意的是,为开发人员开发框架或工具,我认为这本书在今天仍然非常有意义。

Builder:因为在OOP中,对象通常包含太多数据,您需要控制如何正确地实例化它们。即使使用重载的构造函数,实例化时的数据验证也可能变得杂乱无章。您喜欢使用带有方法链接的流畅接口(assert(...).not().equalTo(...))的测试框架吗?你猜怎么着,它的灵感直接来自构建器设计模式。

原型:我经常听到人们抱怨JavaScript太复杂了。虽然我不认为这种语言使开发人员编写不易出错的代码变得容易,但我通过基于原型的本质(由原型设计模式准确地描述)的角度更好地理解了这种语言。

大多数结构模式:虽然每个人都专注于OOP的不好的部分,即继承,但所有这些设计模式都专注于可组合性。如果你想时下很酷,你可以说你更喜欢“组合而不是继承”。如果您认为组合仅仅是将对象相互嵌入,那么您应该阅读结构化设计模式这一部分。例如,您可能知道Python中的装饰器或Java/C#中的注释,它们派生自装饰器设计模式。

责任链:我想我们都同意在我们的现代Web框架中使用和实现中间件有多棒。只需使用或编写接受下一个处理程序(请求对象)的函数即可。通过.use(...)将其传递给您的Web框架实例。方法,您就完成了。这就是责任链模式的全部意义所在。所有Rails、Django和Laravel开发人员都知道这是NIH。

迭代器:这一点现在看起来很明显,也许在使用指针算法迭代数组很常见的时候就不那么明显了。今天,迭代器甚至隐藏在标准库后面,以实现更高的抽象功能,但它们仍然存在。我没有看到一种更通用的方法来使用相同的公共API来实现数组、树或图的遍历(不过,它们是迭代最后那些数据结构的更好方法)。

观察者:对于最后一个,这里是本书中的逐字定义:“定义对象之间的一对多依赖关系,以便当一个对象更改状态时,它的所有依赖项都会被自动通知和更新”。现在,如果我们看看一些现代技术,这不是与PubSub模型或Reaction挂钩产生了共鸣吗?

总而言之,我并不是说这本书不老,恰恰相反:当它以90年代的用户界面为例时,你可以感觉到它。我只是在倡导我们的工业及其工人在过去30年里发生了很大的变化,我敢说比其他任何行业都要多。但这不应该成为抹杀多年精心研发和文档编制的借口,我们的现代工具如今仍然依赖这些研发和文档,以及这些研发和文档背后的人。

因为很多人抱怨他们永远读不完这本书,下面是第351页“从设计模式中期待什么”一节的节选:

可以说这本书成就不大。毕竟,它没有提供任何以前没有使用过的算法或编程技术。[…]。它只记录现有的设计。您可能会得出结论说,它是一个合理的教程,但它肯定不能为有经验的面向对象设计者提供太多东西。

我们希望您有不同的想法。编目设计模式很重要。它为我们使用的技术提供了标准名称和定义。如果我们不研究软件中的设计模式,我们就不能改进它们,而且也更难提出新的设计模式。