架构的组成部分
说明:
这篇随笔,是我在阅读《代码大全》这本书的【前期准备】这一章节的时候,所作的笔记。
因为翻译著作通常比较冗长,因此我将这一部分简单归纳了一下。
其中,我略去了在现在的软件开发中一般不会遇到的问题,斜体部分是我结合个人工作经历的一些理解(我主要从事的是java-web系统开发)。
原文见于《代码大全》P45。
在进行架构设计之前,我们首先应该明白架构应当由哪些部分组成,这样在每一次自行设计架构,或运用别人设计好的架构的时候,都能够迅速地找到最重要的组成部分。
1、程序组织。
- 以概括的形式对整个系统作一个综述,描述组织结构。
- 系统由哪些构造块(子系统)组成。比如用户界面、命令解释、封装业务规则、访问数据。在Java web中,他们分别为前端、MVC框架、服务器接口,以及mybatis或jdbc等数据库操作工具。
- 应该明确每一个构造块的责任和负责的区域,不同的构造块之间应该尽量独立。比如我们常见的前后端分离式开发,controller、service、dao三层设计(如果用jsp等技术做界面展示,则为四层)等。
- 应该明确不同构造块之间的通信规则,对于每个构造块,架构应该指出它能使用哪些构造块,或者不能使用哪些构造块。比如规定controller和service层传参必须使用POJO类,controller能使用service层,但不允许直接调用dao层等。
2、数据设计
- 数据库设计时采用何种规范?为何如此设计?比如是使用自增 id还是由代码生成 id等。
- 数据通常只应由一个或一组类来访问。
3、业务规则
- 架构是否依赖特定的规则,以及架构需要作哪些特别设计来适应这种规则?比如同步问题
4、安全性
- 应该描述实现设计层面和代码层面的安全性的方法。比如如何处理缓存,如何处理非受信数据,如何加密等等。
5、性能
- 应该详细定义性能指标。
- 应该详细定义不同性能之间的优先顺序。(如响应速度、内存、并发数等等)
- 详细描述:
- 在当前设计下,为什么能达到性能要求?
- 系统所能承受的最大负荷?
- 当业务量增大时,哪些部分可能会最先达不到性能指标,风险最大?
- 为了满足性能指标,需要在哪些地方进行特殊的算法/结构设计,对开发成本和周期有何影响?
6、可伸缩性
- 架构应该描述系统如何应对诸如用户数量增长、访问量增长、数据库记录数增长等业务不断增长的情况。
- 如果预计业务不会增长(或增长不会超出预期),则架构应当明确地列出这一假设,比如一些公司内部使用的erp软件、财务系统等。
7、国际化/本地化
- 将一些提示信息、帮助信息、错误信息等等集中管理,而不是分散在代码各处,以便在不同的语言环境中能够轻易替换。
- 尽量做到让不懂技术的人也能去维护这些字符串
- 决定是在配置文件中配置这些信息,还是可以通过数据库动态修改?为什么?
- 总之,要尽量做到在不修改源代码,或者不重启服务器(假如有的话)的情况下,就能做到全部替换。
8、输入/输出 Input/Output
- 定义读取和写入策略
- 应该描述在那一层检测I/O错误:在字段、记录、流、或者文件的层次。
9、错误处理
- 在什么层次上处理错误?是否规定某一个层次无权处理异常,必须全部将其抛出?
- 指出在进行数据验证的时候,是每个类都需要进行数据验证,还是规定只需要某一个层次或某一些类需要进行验证,并且另外的类则可以直接假设数据是被验证过的、值得完全相信的。
- 是使用环境內建的异常机制,还是自己建立一整套新的机制?比如在java中,自定义一些继承自Exception类的异常类。
10、容错性
- 在遇到错误的时候,是否能迅速从错误中恢复(比如关机、重启),并清除其不利影响?
11、可行性
- 架构师多半会关注系统的各种能力,例如是否达到性能目标,能够在有限的资源下运转,实现环境(运行环境)是否有足够的支持。
- 架构应该论证系统的技术可行性。如果在任何一个方面不可行都会导致项目无法实施,那么架构应该说明这些问题是如何考虑的。
12、过度工程
- 过度工程师指程序员为了使系统拥有超过需求中定义的能力而进行的额外工作。
- “健壮性”是指“系统在发生错误之后继续运行”的能力。
- 架构描述的系统应该比需求描述的系统更健壮。
- 组成系统的各部分不应该只在最低限度上满足健壮性要求。
- 应该将精力均匀地花费在系统各部分的“过度工程”上面,不应该因为个人好恶,出现“某些部分异常健壮,某些部分勉强健壮”。
13、不要重复造轮子
- 关注行业里已有的各种组件、技术,看是否可以满足自己的需求;
- 自己需要的组件、技术是否开源?如果不开源,成本多少?
- 自己重新开发,和直接购买相比,哪一个更有优势?