本文最初发表于作者个人博客,经原作者 Tomas Tulka 授权,InfoQ 中文站翻译并分享。
如今已是 2021 年,IT 已经吞噬了整个世界,我们所开发的工具使得像 OOP(Object Oriented Programming,面向对象的程序设计)这样上世纪 60 年代的范式严重过时,对不对?嗯,不是那样的。
最起码在主流上,面向对象的设计为软件开发提供了从代码到系统架构的最有利方法。不过,这只是在做得正确的情况下。
仅仅通过使用关键词 object
或 class
,并不会创建面向对象的代码。甚至在 Java 或 C# 之类的面向对象编程语言中,人们也可以轻松地编写完全非面向对象的代码,但是只有通过使用 OOP 原则,我们才能使程序真正地面向对象。
尽管这些原则几十年来一直为人所知,但是,即使是在 2021 年,大多数的开发者仍然对其知之甚少。我看到越来越多的人在使用结构化编程,这是一种比 OOP 本身更古老的技术。
这使得系统的设计不够理想,难以维护、扩展和推理。易出差错、易受攻击、分布式单体只是我们熟悉的一个例子。
在学校获得的知识是一个良好的基础,但还远远不够。要把注意力集中在理解上,而不只是在知道上;要学习原则而不是实践。
面向对象设计和编程原则
那么,最基本的原则是什么呢?
一个对象由它的契约来定义。
一个对象的契约定义了该对象可以做什么,而非它如何做。从外部看对象,不应该对其实现有任何的了解。契约不能被违反;对象的工作是保护其不变量。业务目标是稳定契约的牢固基础。
对象是自主的。
你不应该要求一个对象提供用于特定动作的信息。取而代之的是,要求该对象为你执行该动作。任何对象都不能对其他对象进行操作。对象是主动的实体,而不是被动木偶。
所有数据都是私有的。
对象必须隐藏解决特定业务问题所需的所有数据和其他细节。如果数据并非私有的,它将成为契约的一部分。对象与数据结构的区别在于:对象是实体,数据结构是透明的。更为正式的说法是,我们谈论的是封装和信息隐藏的概念。
这些原则听起来很简单,但是简单常常不是容易达到的目标。与简单的解决方案相比,程序员更喜欢“聪明”的解决方案;例如,他们通过使用私有属性掌握了封装等 OOP 实践,但通过 getter 和 setter 暴露了这些属性,从而违反了信息隐藏原则。
当然,这个清单并不是固定的,我们还可以添加很多其他的内容,如可组合性、所有的 SOLID 原则等等。但是,上面三个概念比其他的都要重要,同时也是最难实现的。结果是,它们经常被完全忽略。最重要的是,它们在软件开发的所有层次上都具有普遍性。
面向对象的微服务
现在,如果没有提到微服务,任何技术文章都是残缺不全的,而微服务是一种非常流行的构建分布式系统的模式。
面向对象的设计如何在微服务架构中应用?首先,让我们回顾一下(微)服务的定义:
特定业务能力的技术权威是服务。
现在,什么是业务能力?它是企业做什么、能做什么的一种表达。业务能力是定义高内聚服务边界的关键。它是一种执行业务能力的特定功能。功能定义了系统的行为。
服务是自主的;其运作能力不受其他服务的控制或限制。
服务是独立的、自包含的,不受外部控制和约束。服务可以自行决定。服务越是自主,它们之间的耦合就越松散。
任何数据或规则都必须只为一个服务所拥有。
换句话说,服务必须封装它所操作的所有数据和实现细节。我们谈论的是一种无共享的架构,其中每个请求都由单个节点来满足。
用几个要点来概括,一个服务:
取决于其能力;
拥有自己的数据和规则;
完全在控制之中。
这听起来很熟悉吗?当然是啊!从概念上讲,服务仅仅是系统层面上的一个对象。技术细节不同,但是相同的观点也适用。了解面向对象设计的原则将有助于你构建易于维护、高内聚和松散耦合的微服务。
结语
现在是 2021 年,我们还没有清楚地知道怎样去开发我们的软件。IT 产业正在快速发展,需求正在快速变化,我们跟不上。五十年前,面向对象的设计和编程的伟大原则被定义。在今天,它们仍然能教给我们很多东西,只有正确的学习和采纳才行。
面向对象的设计是一种整体方法。它可以成功地应用于软件开发中的各个环节。
总而言之,面向对象的设计和编程的原则是我们所拥有的最好的。而这种情况不会很快改变。
作者简介:
Tomas Tulka:软件开发者,博主。
原文链接:
评论