The following text is a partial translation of the original English article, performed by ChatGPT (gpt-3.5-turbo) and this Jekyll plugin:
模型-视图-控制器(MVC)是我们都非常熟悉的一种架构模式。对于几乎所有的用户界面和Web框架来说,MVC已经成为事实上的标准。它方便易用,简单高效。对于过程式编程者来说,这是个很棒的概念。但是,如果你的软件是面向对象的,你应该和我一样不喜欢MVC。原因如下。
MVC架构的样子如下所示:
[控制器] -向下- [模型] [控制器] -向下- [视图]
控制器负责处理从模型中接收到的数据,并将其注入视图中—这正是问题所在。数据逃离了模型,变得”裸露”,这是一个很大的问题,正如我们之前所说。面向对象编程的核心是封装—数据隐藏。
MVC架构恰恰相反,它通过”暴露”数据而隐藏行为。控制器直接处理数据,对其用途和属性做出决策,而那些本应了解数据并将其隐藏的对象却变得无力。这正是任何过程式架构建立的原则;代码掌控数据。例如,看看这段C++代码:
函数print_speed()
是控制器。它从模型load_from_engine()
获取数据s
,并通过视图printf()
渲染出来。只有控制器知道这些数据是以英里每小时为单位的。引擎返回的是没有任何属性的int
类型。控制器只是假设这些数据是以英里每小时为单位的。如果我们想在其他地方创建一个类似的控制器,我们将不得不一次又一次地做出类似的假设。这就是所谓的“裸数据”问题,它会导致严重的可维护性问题。
这是上述代码的面向对象替代方案(伪C++代码):
在这里,SpeedFromEngine.speed()
以整数形式返回以英里/小时为单位的速度;FormattedSpeed.speed()
返回"%d mph"
;最后,PrintedSpeed.to_str()
返回消息的完整文本。我们可以称它们为“模型、视图和控制器”,但实际上它们只是相互装饰的对象。它们仍然是同一个实体—速度。但通过装饰,它变得更加复杂和智能。
我们并不是将速度的概念分解开来。速度就是速度,无论是谁使用它和在哪里展示它。它只是从装饰器中获得新的行为。它在成长,但永远不会分崩离析。
总结一下,控制器是MVC三元组中的一个纯粹的过程化组件,它将模型转化为被动的数据持有者,将视图转化为被动的数据渲染器。控制器,持有者,渲染器… 这真的是面向对象编程吗?
Translated by ChatGPT gpt-3.5-turbo/42 on 2023-11-28 at 15:40