什么是软件架构
在维基百科中,软件架构的定义如下
- 架构模式是一个通用的、可重用的解决方案,用于在给定上下文中的软件体系结构中经常出现的问题。架构模式与软件设计模式类似,但具有更广泛的范围。
这个定义虽然不长,但我刚开始学习软件开发的时候,却读了好多遍都还是没有一个清晰的认识。在现在就我而言,软件架构就像是一种与建筑风格很类似的东西。我们在开发前,要根据软件的需求和特性来确定软件的开发架构,就像我们要根据建筑的用途和周围环境来确定我们到底应该使用哪种建筑风格。当我们确定了建筑风格,自然而然就必须要按照这种风格的定义和形式去进行修建,就像是我们确定了软件架构之后,就要按照这个架构所限定的方式去进行开发。
而现在也有很多钟适用于不同形式的软件架构,下面主要就对这些架构进行一个对比:
软件架构的对比
分层模式
- 要求:
- 每个模块都必须属于某个层次,提供给“第N+1层”(上层)服务;同时委派任务给“第N-1层”的模块。
- 任何一个模块,都不得逆层次调用:属于第N层的模块,不得调用(耦合)第N+1层或以上层次的模块。
- 任何一个模块,都不得跨层调用:属于第N层的模块,不应该调用第N-2层或更下层的模块
- 常见形式:
- 表示层(也称为UI层)
- 应用层(也称为服务层)
- 业务逻辑层(也称为领域层)
- 数据访问层(也称为持久化层)
- 优势:
- 只要层次划分准确,可以大大减少重复代码的数量,功能开发更快,更灵活
- 性能提升代码能更好的覆盖了——集中了通用实现代码,也集中了优化部分。
- 可以并行开发,资深人员负责底层,一般人员负责上层。
- 把后期的测试和维护也会更加方便
- 适合:
- 比较大型的功能集成业务,如一般的桌面应用程序,电子商务Web应用程序
- 不适合:
- 简单业务模型,对简单业务进行分层规划会增加很多不必要的代码,陷入过度设计的泥坑。
客户端-服务器模式
- 要求:
- 由服务器和客户端两个部分组成。服务器组件将为客户端组件提供服务。客户端从服务器请求服务,服务器为这些客户端提供相关服务。此外,服务器持续侦听客户机请求。
- 常见形式
- 两层架构——客户端直接与服务器进行交互。这种类型的架构可能有一些安全漏洞和性能问题
- 三层架构——客户端和服务器通过中间件进行交互。中间件被用来执行所有的安全检查和重负载情况下的负载平衡。中间件需要从客户端的所有请求,并做必要的验证后,通过向服务器发出请求。
- 优势:
- 维护简单方便
- 服务器可以更好地控制访问和资源,以保证只有那些具有适当权限的用户可以访问和更改数据。
- 由于数据的集中存储,对数据的更新更容易管理
- 劣势:
- 如果客户端发送的清酒过多,会给服务器端造成很大的压力
- 缺乏一定的安全性,服务器容易被攻击。或者如果服务器突然出现故障,则整改系统都不能正常运行
- 适用情况
- 一些数据需要集中管理的应用系统,如电子邮件,文件共享和银行等在线应用程序
主从设备模式
- 要求:
- 与服务器—客户端模式类似,也由两个部分组成,主设备和从设备。主设备组件在相同的从设备组件中分配工作,由从设备计算每个部分的结果,并将结果返回给主设备,并由主设备得到最终结果
- 常见形式
- 主设备和从设备使用同一个存储仓库
- 使用Future模式
- 优势
- 并行计算,以提升计算性能
- 容错处理,以提升计算的可靠性
- 计算精度,以提高计算的精确程度
- 提高了原始数据的安全性
- 劣势
- 设备之间的通信会出现延迟
- 传输过程可能会出现错误
- 当从设备变为恶意几点,传输错误结果时,缺少原始数据的主设备很难发现
- 适用情况
- 在数据库复制中,主数据库被认为是权威的来源,并且要与之同步
- 在计算机系统中与总线连接的外围设备(主和从驱动器)
管道-过滤器模式
- 要求
- 是一种是面向数据流的软件体系结构,将数据的传输过程形象化为在管道中流通的过程。管道-过滤器模式的重点在过滤器的设置,而过滤器对数据进行依次对应的处理,最终输出结果
- 常见形式
- 输入过滤器——输入过滤器处在问题所在的外部世界与软件系统的边界处,是系统数据流的源点。它负责接收外界信息并转化为系统所需的数据流。
- 处理过滤器——处理过滤器是系统内变换数据流的部件,它有一个入口和一个出口,数据经入口流入,经过处理过滤器内部处理之后从出口流出。
- 输出过滤器——从建立完备的,首尾一致的可重用的软件部件组的角度出发,正如输入过滤器是系统数据流的起点,那么输出过滤器是数据流的终点。
- 优势
- 每个过滤器作为一个单独的执行任务, 可以与其它过滤器并发执行
- 将整个系统的输入输出行为理解为单个过滤器行为的叠加与组合,可以简化程序的实现过程
- 整个系统易于维护和升级,只需要升级某一个比较陈旧的过滤器即可
- 劣势
- 适用的软件形式较少,只能局限于比较少的领域。
- 因为是线型的软件架构,所以只要中间某一个过滤器出现问题,最终的结果就会出现错误
- 适用情况
- 编译器
- 生物信息学的工作流
代理模式
- 要求
- 为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用
- 常见形式
- 静态代理——利用静态代理可以做到在符合开闭原则的情况下对目标对象进行功能扩展。但我们得为每一个服务都得创建代理类,工作量太大,不易管理。同时接口一旦发生改变,代理类也得相应修改。
- 动态代理——相对于静态代理,动态代理大大减少了我们的开发任务,同时减少了对业务接口的依赖,降低了耦合度
- CGLIB代理
- 优势
- 职责清晰——真实的角色就是实现实际的业务逻辑,不用关心其他非本职责的事务,通过后期的代理完成一件完成事务,附带的结果就是编程简洁清晰。
- 代理对象可以在客户端和目标对象之间起到中介的作用,这样起到了中介的作用和保护了目标对象的作用。
- 提供了很高的扩展性
- 劣势
- 由于在客户端和真实主题之间增加了一个代理对象,所以会造成请求的处理速度变慢
- 实现代理类也需要额外的工作,从而增加了系统的实现复杂度。
- 适用情况
- 远程代理——客户端调用Web服务或WCF服务。
- 虚拟代理:根据需要创建一个资源消耗较大的对象,使得对象只在需要时才会被真正创建。
- 防火墙代理
- 智能引用——当一个对象被引用时,提供一些额外的操作,比如将对此对象调用的次数记录下来等。