分钟
我们开始这次对话时,Martin 询问了对 Rails(以及其他类似框架)的态度应该是什么。我们应该将它们视为平台,接受它们的所有优缺点吗?或者我们应该将它们视为一组组件,您可以从中选择您喜欢的框架部分,而忽略您不喜欢的部分。 Badri 回答说,虽然 Rails 在模块化方面已经取得了很大进展,但今天可以更容易地对 Rails 进行子集化,而不是替换整个组件。例如,在不需要发送或接收电子邮件的应用程序中,可以省略 Action Mailer。可以将 Action Support 拉入标准 Ruby 应用程序中,并获得它提供的大量便捷方法和核心扩展。也就是说,例如,不能简单地用 Node.js 中的事件系统替换 Rails 请求-响应调度周期。这是因为 Rails 的构建是为了支持一种非常特定类型的应用程序。 Martin 笑着说,指的是 Rails 是一个旨在构建 Basecamp 的框架的说法。
Badri 反驳说,Rails 的最佳选择是与关系数据存储对话的深度网络应用程序。换句话说,您的应用程序的用户数量有限,无论人是通过 Web UI 使用您的应用程序,还是其他机器通过 REST API 与您的应用程序交互,Web 都不是偶然的元素。 Badri 进一步推测,也许问题在于人们过早地决定使用框架。框架为了方便而放弃了许多设计选择 - 这意味着也许我们应该了解我们希望如何设计我们的应用程序,然后选择一个不会禁止这些设计选择的框架,而不是先选择一个框架,然后让它妨碍您希望如何设计系统。
Martin 回答说,使用框架并以某种方式设计应用程序的选择可能是在一段时间之前做出的。也就是说,框架设计者可能会选择另一条道路,而您可能会发现自己陷入困境。Martin 随后总结了我们迄今为止的对话,他说,如果您处于框架的最佳位置,那么将其视为一个平台是有意义的,而不是花费精力预先将自己与未来可能发生的变化隔离开来。 Badri 同意这个总结,并表示有些人发现他们添加的额外层在指导他们的设计思路方面是有益的。也就是说,他个人倾向于将 Rails 作为一个平台来使用。
他个人倾向于将框架用作平台,这是因为他过去在尝试规避框架方面的经验。以 .NET 中的富客户端框架为例,他回忆起有一次他参与了一个应用程序的开发,他们试图不使用双向数据绑定。由于团队中的一些成员认为应该对应用程序进行测试,因此他们尝试通过不使用数据绑定机制来创建一个简单视图。这导致了相当大的混乱,因为框架的设计初衷并不是这样使用的,我们最终编写了太多的代码,并重新发明了框架的主要部分。希望逆框架而行的团队需要了解这种成本。也许这种成本有时是值得的,但不可避免的是,这种成本往往是巨大的。他补充说,如果团队希望对框架进行重大更改,他们可能会希望选择一流的库并构建点菜式应用程序。 Martin 重申,关键是要在充分考虑两种方法的成本和收益之后,根据需要做出明智的选择,是将框架用作平台还是组件套件,而不是在没有充分考虑的情况下盲目地完全采用其中一种模式。
Martin 询问框架是否值得为您做出某些设计选择,以及这是否能让团队的新成员更快上手。 Badri 回答说,这是一般框架的优势 - 包括 Java 世界中的 Spring 等框架。他声称,他个人发现人们在使用框架时遵循的通用使用模式更为重要 - 他举了一个例子,说明在 2001 年左右的企业 Java 世界中,几乎每个应用程序都有自己的事务边界位置和实现方式。这是他在参与的每个应用程序中都必须反复学习的东西。另一方面,在 Rails 中,有一个常见的模式,即在包装每个请求-响应周期的过滤器中启动事务并回滚或提交事务。这种学习对于能够从一个 Rails 代码库转移到另一个 Rails 代码库非常有用。
Martin 呼吁人们不要将框架强加到不适合它们的地方。 Badri 补充说,虽然这一点完全正确,但 Rails 确实为框架没有意见的地方的各种设计选择敞开了大门。他用他参与的项目的几个例子来说明了这一点。 第一个例子是从版本控制系统中获取提交数据,以便可以在应用程序中其他数据的上下文中显示这些数据。由于需要使应用程序在没有此功能的情况下也能工作,并且还需要将来自多个版本控制系统的数据全部提取到应用程序中,因此他们设计了一个端口,用于定义此信息进入系统的入口点。该端口成为通过适当使用适配器来适应所有传入数据的单一入口点,这些适配器适用于到达该端口的每种数据。
第二个例子是双向通信,他们构建了一个 Jabber 聊天室机器人,该机器人会将团队聊天室中与正在处理的故事相关的消息提取出来,并将它们作为讨论线程附加到管理待办事项的应用程序中的故事中。再一次,因为此功能不是应用程序的核心,并且他们需要让各个团队根据需要打开或关闭此功能,所以他们实现了一个网关,负责聊天室和核心应用程序之间的所有通信,而核心应用程序完全不知道是否配置了此功能。这为他们提供了良好的领域逻辑核心隔离级别。
Martin 总结了这两个例子,他说使用 Rails 并不是要完全避免隔离。他强调,您不想将自己与平台隔离,但您确实想将自己与外部部分隔离。 对应用程序的哪些构成外部部分以及哪些构成内部部分之间的区别,使我们回到了我们开始使用六边形架构模式进行聊天的起点。