设计软件架构就是一个考虑平衡的过程。
应用软件架构设计的主要步骤为:
(穿插《梦想改造家》建筑设计师对房屋改造的例子助于理解 )
一:了解架构目标
在进行工作之前,对架构目标是要进行确定和了解才能找出方案进行解决。
需求调查就是弄清楚成品所要达成的功能,也就是找到设计架构的目标。
(1)了解涉众的需求,还要考虑涉众的利益。
(2)考虑实际的条件限制。如技术、部署、使用等限制
~~如同建筑设计师在改造房屋前,先对房屋实地考察,房屋的使用者始终是人,除了对房屋各个结构的数据进行了解外,还要了解人对改造后的房屋的期望,人的生活习惯等,建筑设计师也要观察很多隐藏的细节(一些生活上的不方便)
所以了解了架构目标,也是帮助确定什么才是目标,什么才是困难点。有助于之后设计进行的权衡。
二:软件的系统场景和用户场景
设计软件实现功能更能给设计的过程带来实际的考虑。能体现软件的价值,和架构特点。
(1)系统场景:软件系统中各个功能模块之间的交流、数据传输和存储、对信号的接受或拒绝等验证功能等等。(系统内部)
PS:a.系统场景应当是业务的关键部位,不可或缺的,对应用整体都有重要的影响。
b.关系到功能属性和质量属性两个方面。能影响架构设计中的侧重性,比如检索操作对性能就具有要求了,希望能够更快。
~~建筑设计师在屋顶设计了天窗,除了解决光照问题,也解决了房子通风问题。
(2)用户场景:用户触发或者受用户控制的场景,如用户创建表单,检索或者浏览产品等等。(与人相关)
PS:(突出架构特点的用例举例)
a.用户在仓库管理程序中创建一个表单,输入信息并提交。
b.用户在仓库货存程序中查询或浏览货品的详细信息,并将数据进行更新。
~~建筑设计师对桌子进行了改进,用户对桌子的使用,多为读书学习,也可以将桌子内部的缝纫机取出使用。
三:确定应用的实际问题
处理应用置于周遭环境中的情况,考虑具体的条件限制,让架构设计更加实际。
- 给应用类型定位:属于移动设备应用、大型设备应用、网络应用等等
- 移动设备应用:类似手机等移动端上运行的应用可以支持未联网或者偶然联网的场景,移动设备的资源占用也将成为这种设计条件的限制。
- 大型设备应用:类似大型计算机群上使用的应用,在图形界面上显示数据,支持未联网的情况下。
- 网络应用:如网页等,通常支持联网场景,不同设备通过浏览器等多种应用方式进行访问。
- 部署限制:考虑企业的政策和程序及目标部署设备,如网络布局,在现实因素的影响下,要折中考虑利与弊。在架构设计早期考虑这些问题,能够解决应用和设备架构之间的冲突。
PS:非分布式与分布式架构
非分布式:应用的数据、呈现、运算等在同一服务器(同一物理级)上
优势:架构更简单,在本地调用(单一使用)性能上更有优势,反应处理速度更快更稳定。
劣势:难于扩展,资源难以分配。
分布式:将上面的各个元素分布在各个单位中(不同物理级)上
优势:易于扩展,可以独立运行需要的功能,各层可以利用良好的资源。
劣势:远程调用会产生网络延迟、连接不稳定等问题。交互更复杂,成本更高。
~~建筑师改造房子之前,住户狭小的卫生间就冗杂了洗衣机、洗漱台、马桶等,当一家人有一人需求其中一样时,对于其他人就不方便了,并且其他资源并未使用,使用者就将其占用了,虽然方便了一人在卫生间完成所有工作,但对于多人的情况时,并不适用。这就好比上面所讲的非分布式。
~~建筑师改造房子之后,住户卫生间内的洗衣机搬至楼上,节约了空间,然后马桶和洗漱台间有活动门板,隔开互不影响。虽然洗衣机在楼上,有着上下楼的路程,但其影响并不大,且资源得到了有效利用。这就好比上面所讲的分布式。
在不同的场景下,不同的处理方式,有着更好的效益。
- 确定架构的特点
企业的设计与实现能力、开发人员的能力与经验、设备限制与部署场景等。
主要架构模式有几下几种:
-
- 客户服务器。分离系统,客户向服务器发送请求。
- 基于组件。将应用设计分解为可重用的组件,用户界面良好。
- 分层。以层为单位将系统分解为各功能相近的组。
- 消息总线。为所有连接到系统的组件定义一组通用格式,因此各组件无需了解接收方的实际信息。
- 面向对象。一种将任务以对象为基础进行分解的程序设计方法。
- 面向服务(SOA)。应用根据合约与信息以服务的方式呈现或使用功能。
一个完整的结构通常包含几种模式。比如,一个分层的架构可以与基于组件、面向对象或面向服务的架构模式一起使用。可以这样选择架构模式。
以下是选择客户服务器架构模式的情况:
-
- 你的应用是基于服务器的,可以支持多个客户端。
- 你创建的是通过网络浏览器呈现的网络应用。
- 你的业务过程需要能被公司所有人使用。
- 所创建的服务要供其它应用使用。
- 你想让数据存储、备份和管理功能集中化。
- 你的应用必须支持各种客户端类型和设备。
以下是选择基于组件的架构模式的情况:
-
- 你已经有了合适的组件,或者可以从第三方获得合适的组件。
- 你的应用永远都是用于执行程式化的功能的,可能不需任何输入。
- 你的应用相对简单,无需一个完整的分层架构。
- 你的应用是为了满足特定的需求而产生的,没有用户界面或业务过程。
- 你想把使用不同代码语言编写的组件结合到一起。
- 你想创建一个便于替换和更新私人组件的插件式架构。
以下是选择分层架构模式的情况:
-
- 应用比较复杂,所以你想分组各种功能问题以简化问题。
- 你想通过减少依赖关系来提高可维护性与扩展性。
- 你已有通过服务接口呈现合适的业务过程的应用。
- 你的应用必须支持各种客户端类型和设备。
- 你想实现复杂的和/或可配置的业务规则和过程。
以下是选择系统总线架构模式的情况:
-
- 当前的应用之间有互操作。
- 你在执行一个需要与外部应用进行交互的任务。
- 你在执行一个需要与寄存在另一个环境中的应用进行交互的任务。
- 当前的应用执行一些特殊的任务,你希望把这些任务整合成一个操作。
以下是选择面向对象的架构模式的情况:
-
- 你要根据实际对象和行为对应用进行模拟。
- 你已有符合需求的合适的对象和类。
- 你需要将逻辑与数据一起封装到可重用的组件中。
以下是选择面向服务的架构模式的情况:
-
- 你能够访问到适合的服务,或者可以购买到托管公司的所需服务。
- 你希望为包含各种服务的应用程序构建一个统一的用户界面。
- 你在创建SS、SaaS或基于云的应用。
- 你需要支持应用中各段之间的基于消息的交流。
- 你需要以平台无关的方式呈现功能。
- 你希望利用联邦服务,比如认证。
- 你希望以目录的方式呈现服务,并且首次接触这个界面的用户也可以使用。
架构模式了解甚少,例子以后补充
- 确定相关的技术
技术的选择和应用模式有直接的关系,要考虑哪种技术能给予架构模式、应用模式、应用质量属性上的支持。
四:确定危险区域
质量属性是在设计时要考虑的侧重方向。
不同应用有对某方面有及其严格的要求,比如飞机管理系统,对于安全性和性能要求就十分高,也要对其他质量属性进行权衡。
~~建筑设计师对于狭小房屋的改造,他就尤其注意了两个方面:安全和舒适。当然公共场合如教堂,就可以偏向外观和便利性。
如下是各个质量属性的基本说明:
注意事项
|
|
有效性
|
如何设计故障转移支持
|
|
如何设计一个备用站点
|
|
怎样计划备份与恢复
|
|
如何设计运行时的更新
|
概念完整性
|
如何分离对外部的依赖性
|
|
如何整合旧技术
|
|
如何在不打断客户的情况下发展系统
|
灵活性
|
如何处理动态业务规则
|
|
如何处理动态UI
|
|
如何处理数据与逻辑过程中的变化
|
|
如何处理业务需要的变化
|
互操作性
|
如何让应用在独立发展的同时实现互操作
|
|
如何通过服务接口分离系统
|
|
如何通过层的映射分离系统
|
易维护性
|
如何减少层与组件之间的依赖性
|
|
如何实现一个插件式的架构
|
|
如何选择合适的通信模型
|
易管理性
|
如何了解主要的失败模式
|
|
如何对系统操作与健康状态进行监控
|
|
如何根据负载对系统进行调整
|
性能
|
如何确定缓存策略
|
|
如何设计层间的高性能通信
|
|
如何设计高性能数据存取
|
|
如何有效地管理资源
|
可靠性
|
如何处理不可靠的外部系统
|
|
如何审查请求与任务
|
|
如何对负载进行重定向
|
|
如何处理失效的通信
|
|
如何处理失效的操作
|
|
如何处理异常
|
重用性
|
如何减少层与组件之间的重复性
|
|
如何实现跨系统的共享
|
|
如何实现组件和层之间的功能共享
|
可扩展性
|
如何设计可扩展的层与级
|
|
如何扩展
|
|
如何处理传输与负载的测试点
|
安全性
|
如何解决认证与授权问题
|
|
如何防止恶意输入
|
|
如何保护敏感数据
|
支持
|
如何设计审查与记录
|
|
如何设计使用问题信息的记录
|
易测性
|
如何设计才能方便测试
|
|
如何设计单元测试
|
|
如何设计UI自动化
|
可用性
|
如何设计才能让用户有更多的权限
|
|
如何改善响应性
|
|
如何避免常见的用户体验问题
|
架构框架代表层与级上可能遇到的交叉问题,这也关系到软件各功能模块的独立性。好比车间里的工作,各司其职,做好职内的事,不会引发其它问题。
比如下方的考虑的交叉问题中,验证的如何限制及拒绝输入,如果这一简单的问题在网页注册中未解决好,就将会出现非法字符存入数据库,导致错误。无法利用此注册信息登录等额外的问题。
领域
|
描述
|
认证与授权
|
如何选择认证策略
|
|
如何选择授权策略
|
|
如何在不同层与级之间传递身份消息
|
|
如何在不使用活动目录的情况下存储用户的身份信息
|
缓存与状态
|
如何选择合适的缓存技术
|
|
如何决定缓存哪些数据
|
|
如何决定在哪里缓存数据
|
|
如何检查过期策略
|
通信
|
如何为不同的层与级选择合适的通信协议
|
|
如何设计层之间的松耦合
|
|
如何实现异步通信
|
|
如何传送敏感数据
|
组合
|
如何为用户界面选择组合模式
|
|
如何避免UI模块之间的依赖性
|
|
如何处理UI模块之间通信问题
|
并发与事件
|
如何处理并发线程
|
|
如何选择积极并行与保守并行
|
|
如何处理分布式事件
|
|
如何处理长期事件
|
配置管理
|
如何确定需要配置的信息
|
|
如何确定在哪里储存配置信息
|
|
如何保护敏感配置信息
|
|
如何处理簇中的配置信息
|
耦合与内聚
|
如何选择合适的层策略来分离问题
|
|
如何在层里设计高内聚的组件并对其分组
|
|
如何确定松耦合是否适合层里的组件
|
数据存取
|
如何管理数据库的连接
|
|
如何处理异常
|
|
如何改善性能
|
|
如何处理二进制大对象(blob)
|
异常管理
|
如何处理异常
|
|
如何记录异常信息
|
|
如何在需要的时候进行通知
|
日志与器械
|
如何决定记录哪些信息
|
|
如何让日志可修改
|
|
如何确定需要什么等级的器械
|
用户体验
|
如何提高任务的有效性与效率
|
|
如何改善响应性
|
|
如何提高用户权限
|
|
如何改善外观与体验
|
验证
|
如何确定在什么位置怎样执行验证
|
|
如何验证长度、范围、格式、类型
|
|
如何限制及拒绝输入
|
|
如何整理输出
|
工作流
|
如何选择合适的工作流技术
|
|
如何处理同一工作流中的并发问题
|
|
如何处理工作流中的错误
|
|
如何编排工作流中的过程
|
软件架构大体步骤如上进行,从了解目标,到考虑运行场景,到实际条件限制,最后对软件系统细节来决策。是一个综合性的设计,是对可行性和扩展方面的设计。