还有一些原则是关于软件结构应该如何安排的。比如下面这些。
- 分层策略 :因为每一层都独立于周围,分层架构通常出现在有高度灵活性的软件系统中。比如,你可以把软件系统解构为UI(User Interface,用户界面)层,业务层和数据访问层。使业务层完全独立于数据访问层意味着(通常)可以实现在不影响业务或UI层的情况下切换数据访问。能这样做是因为数据访问层向业务层呈现了抽象,而不是业务层自己直接处理数据存储机制。如果想以这种方式安排软件结构,你就应当确保开发团队里每个人都明白这个原则。“UI组件或域对象里没有数据访问逻辑”是该原则在实践中的一个具体例子。
- 业务逻辑的位置 :有时候,出于性能或可维护性的原因,你要确保业务逻辑总是驻留在一个地方。对于连接互联网的移动应用程序,你可能想要确保服务器尽可能多地处理发生的请求。或者如果你在整合一个已经包含了大量业务逻辑的遗留后端系统,可能想要确保团队里没有人打算复制它。
- 高内聚、低耦合 、SOLID 1 等:有很多关注点分离相关的原则,专注于构建不需要太多依赖就能完成工作的高内聚的小结构单元。
- 无状态组件 :如果你在构建一个需要很强可伸缩性的软件,那么尽可能把组件设计得无状态,就是一种确保可以通过复制组件来对系统进行横向扩展从而分担负载的方式。如果这是你的可伸缩性策略,每个人都需要明白他们必须使用相同的模式来构建组件。这有助于避免将来出现任何讨厌的意外和可伸缩性瓶颈。
- 存储过程 :关系型数据库的存储过程就像马麦酱2 ——你对它们不是爱就是恨。用不用存储过程都各有优缺点,但当团队只是选择一种数据访问的方法并坚持,我还是倾向于存储过程。然而,每条原则都有例外。
- 域模型:丰富与贫瘠 :有些团队喜欢在自己的代码中有很丰富的域模型,构建本质上非常面向对象的系统。另一些则倾向于更贫瘠的域模型,对象只是被粗粒度组件和服务使用的数据结构。方法的一致性有很长的路要走。
- HTTP会话的使用 :如果你在构建一个网站,可能想或者不想用HTTP会话来存储请求间的临时信息。这通常取决于很多事情,包括你的伸缩策略是什么,会话支持对象到底存储在哪里,服务器出现故障时会发生什么,你是否使用粘性会话,会话复制的成本,等等。再次,开发团队的每个人都应该明白想要的方法,并坚持下去。
- 始终一致与最终一致 :很多团队都发现,他们往往需要为满足复杂非功能需求做出权衡。比如:有些团队用数据一致性换取性能或可伸缩性。我们能看到所有的Facebook3 状态更新,但是否都能立即看到真的重要吗?你的语境将决定立即或延迟的一致性是否妥当,但一致的方法很重要。
1 http://en.wikipedia.org/wiki/SOLID_(object-oriented_design)
2 http://en.wikipedia.org/wiki/Marmite ,一种黏稠状、深棕色并且有鲜明特色风味的酱,通常抹在面包等食品上食用。——译者注
3 http://facebook.com/ ,著名社交网站。——译者注