1、技术约束。
时间和预算是大多数软件开发者都熟悉的约束,还有一些在大型组织里经常碰到的一些技术相关的约束:
(1)批准的技术清单(目的是限制组织必须支持,运行,维护和购买许可证的技术)
(2)现有系统的互操作性(有时别的系统需要和你构建的系统整合,这时组织性的约束规定了你可以用于整合的协议和技术)
(3)目标部署平台(包括嵌入式设备、windows或Linux服务器的可用性,以及云)
(4)技术成熟度(有些组织乐于采用有风险的尖端技术,拥抱这种进步带来的风险)
(5)开放源代码(开源许可证的混乱也阻碍了一些组织完全采用开源项目)
(6)供应商关系(就像生活中的很多事情,不是你知道什么,而是你认识谁)
(7)内部知识产权(当你需要找到一个库或框架来解决所面临的问题,你必须使用组织自己内部的日志库、持久化框架或通信基础设施服务)
2、人员约束。
开发软件可用的技术和方法受限于你周围的人。
你的开发团队有多大
他们有什么技能
如果你的开发团队需要扩充的话,能有多快
如果需要的话,你能够提供培训、咨询和专家吗
如果在交付后转交你的软件,接手的维护团队拥有和你的开发团队相同的技能吗
3、被强加的约束通常是坏的,但往往是出于好的理由。软件架构也事关引入约束,在一个代码库里面你到底想要多少个日志库或持久化库?
4、约束可以划分等级。
比如功能需求,有些约束比其他的更重要。约束通常是你需要绕过的障碍,但有时候也能相互权衡。
5、开发原则。
编码标准和规范。
自动化单元测试。
静态分析工具。
6、架构原则。
(1)分层策略(因为每一层都独立于周围,分层架构通常出现在有高度灵活性的软件系统中。比如,可以分为UI用户界面层、业务层和数据访问层,使业务层完全独立于数据访问层意味着可以实现在不影响业务或UI层的情况下切换数据访问。能这样做是因为数据访问层向业务层呈现了抽象,而不是业务层自己直接处理数据存储机制)
(2)业务逻辑的位置(有时出于性能和可维护性的原因,需要确保业务逻辑总是驻留在一个地方)
(3)高内聚,低耦合,SOLID等(有很多关注点分离相关的原则,专注于构建不需要太多依赖就能完成工作的高内聚的小结构单元)
(4)无状态组件(一种确保可以通过复制组件来对系统进行横向扩展从而分担负载的方式,用来构建一个需要很强可伸缩性的软件)
(5)存储过程(用不用存储过程,都各有优缺点)
(6)(领)域模型(有些团队喜欢在自己的代码中有很丰富的(领)域模型,构建本质上非常面向对象的系统。另一些则倾向于更少的(领)域模型,对象只是被粗粒度组件和服务使用的数据结构)
(7)Http会话的使用(如果你在构建一个网站,可能想或不想使用http会话来存储请求间的临时信息,这取决于很多,比如你的伸缩策略是什么,会话支持对象到底存储在哪里,服务器出现故障时会发生什么,是否使用粘性会话,会话复制的成本等)
7、技术不只是一个实现细节,你做出的技术决策跟你分解、安排和设计软件系统的方式同等重要。
架构图应该包括技术的选择。
如果你有复杂的非功能需求,比如高性能或可伸缩性,你必须搞清楚你的技术(和架构)选择是否会管用。
约束会影响你给出的软件架构,不能忽视它。
缺乏一致性的方法会导致代码库难以理解、维护和增强。增加单独可移动部件的数量也会让部署、运营和支持变得复杂。
如果你不明白选择X技术而非Y的权衡,那就不应该做决策。设计软件系统的人要懂技术,这很重要。
8、更多分层等于更高复杂度。
所有的架构决策都少不了权衡。更多的可移动部件意味着更多的设计、开发、测试和部署工作。对于时间和预算,没有什么是免费的。
9、敏捷方法的成功告诉我们,要定期与最终用户或他们的代表沟通,才能确保我们构建的软件符合他们的需要。但软件的使用者只是利益相关者的一类,通常还有很多其他类型:
(1)当前的开发团队(他们需要了解架构,知道驱动力是什么,这样他们给出的解决方案才会与架构一致)
(2)未来的开发团队(需要掌握同样的信息,才能明白解决方案如何运作,才能以一致的方式修改他)
(3)其他团队(你的软件需要和环境中的其他系统集成,所以每个人对它如何工作达成共识很重要)
(4)数据库管理员(他们需要了解你的解决方案如何使用他们的数据库服务,比如从设计和优化到容量规划和归档)
(5)执行/支持人员(业务人员需要了解如何运行和支持你的系统,比如从配置和部署到监测和故障诊断)
如果你认为自己能够闭门造车独立完成一个软件结构,就可能错了。软件架构并非是孤立的,软件设计过程是一个不断深化交流的过程。