分层原则

2005年1月7日

过去几天,我一直参加由Jimmy Nilsson主持的挪威企业软件研讨会。在研讨会期间,我们进行了一次会议,我们提出并投票了一系列设计原则。

规则如下。每个人都可以提出良好的分层原则,这些原则将被添加到列表中。对原则的讨论很少 - 仅在需要时进行澄清。人们可以提出他们喜欢的或不喜欢的原则 - 规则是捕捉人们在该领域听到的原则。

一旦我们得到一个列表,就该投票了。我们使用了一种变体DotVoting,每个人获得 10 张赞成票和 10 张反对票。

我将结果列在下面 - 原则遵循格式为正/负的投票。

  • 层之间耦合低,层内内聚高。10/0
  • 关注点分离。11/0
  • 层应该对消费者保持无知(层不应该知道谁在它上面。)4/4
  • 适应性:能够改变。2/0
  • 用户界面模块不应包含任何业务逻辑。10/0
  • 业务逻辑层不包含任何用户界面,也不引用用户界面模块。8/0
  • 层之间没有循环引用。8/0
  • 至少有三种主要层类型:表示层、域层和数据源层。3/9
  • 业务层只使用技术服务的抽象。14/0
  • 按层分离开发团队。1/22
  • 层应该是可单独测试的。12/0
  • 优先考虑层仅与相邻层交互。4/4
  • 层应该谨慎地将较低层暴露给较上层。1/0
  • 层应该隐藏较低层对较上层。
  • 层应该只与相邻层交互。2/3
  • 更改较低层接口不应更改较上层接口。2/5
  • 在层边界进行分布 0/18
  • 层是逻辑工件,并不意味着层之间进行分布。11/0
  • 较低层不应依赖于较上层。6/0
  • 每个层都应该有一个秘密。3/2
  • 层应该对它们的内部保持谨慎。8/0
  • 层应该是可替换的。2/0
  • 层可以有多个相邻的上层。2/1
  • 始终用服务层包装域逻辑。4/5
  • 在层边界重新抛出异常。0/15
  • 层应该是独立可维护和版本化的。2/0
  • 层应该有单独的部署单元(例如,每个层都有单独的 jar 或程序集)。0/7
  • 层可以共享基础设施方面(例如安全)7/0
  • 域层不应与外部系统通信 - 服务层应该这样做。2/3
  • 入站外部接口模块(例如 Web 服务处理程序)不应包含业务逻辑。10/0

显然,你不能从这个列表中读出太多东西。虽然这是一个很好的群体,但它绝不是企业开发专业知识的权威来源。这些原则的措辞也比较宽泛,存在重叠和不精确之处,如果我们有超过一个小时的时间来进行这项练习,这些问题就会得到解决。但是,我怀疑这个列表可能会引发一些思考和讨论。

我问人们是否有让他们感到惊讶的事情。有几个人惊讶地发现,他们经常听到(并且不喜欢)的原则在投票中被否决了。(按层分离开发团队和在层边界重新抛出异常。)同样,人们也很惊讶地发现“业务层只使用技术服务的抽象”获得了如此高的投票,尽管在实践中很少这样做。