架构师培训讲义4高层软件架构的设计.docx
《架构师培训讲义4高层软件架构的设计.docx》由会员分享,可在线阅读,更多相关《架构师培训讲义4高层软件架构的设计.docx(34页珍藏版)》请在冰豆网上搜索。
架构师培训讲义4高层软件架构的设计
第四章高层软件架构的设计
在高层设计阶段,主要工作是分析与设计软件的体系结构。
通过系统分解,确定子系统的功能和子系统之间的关系,以及模块的功能和模块之间的关系,产生《体系结构设计报告》。
这个阶段是系统架构师发挥作用的主要位置,高层架构设计过程设计流程如下。
确定
设计
策略
确定
约束
因素
设计
准备
系统
分解
设计
设计
评审
撰写
文档
在分析阶段,我们建立模型表示真实的世界,以便理解业务过程以及这个过程中所要用到的信息。
基本上说,分析首先是分解,把复杂信息需求的综合问题,分解成易于理解的多个小问题。
然后通过建立需求模型来对问题领域进行组织、构造并且编制文档。
分析建模过程必须要用户参与,并且需要用户解释需求,并且验证建立的模型是否正确。
设计也称之为架构设计,实际上也是个建模过程,它把分析阶段得出的信息也就是需求模型,转换为称之为解决方案的模型。
一般来说架构设计是一个高度技术的工作,一般不需要涉及太多的用户,但需要系统分析人员和部分开发人员参与。
因为系统设计的输出就是开发的蓝图。
下面讨论在这一阶段一系列的原则和思想。
第一节高层软件架构的规划
一、客户服务结构(C/Sarchitecture)
这个结构可以用部署图来表示。
二、多级体系结构(four-tierarchitecture)
这里使用了组件图和部署图。
三、多级体系结构(串行法和团聚法)
四、流处理体系结构(proceduralprcessingarchitecture)
五、代理体系结构(agentarchitecture)
六、聚合体系结构(aggregatearchitecture)
七、联邦体系结构(federationarchitecture)
第二节面向过程的架构设计
面向过程的架构设计,又称之为结构化设计。
它使用“输入–处理–输出”这样一个基本模型,这些模式比较适用于描述商业软件,它们中大多数依靠数据库或者文件,并且不太需要复杂的实时处理。
我们可以使用流程图来记录各个子系统的结构,系统流程图标识了每个程序,以及他们存取的数据。
一、系统流程图
系统流程图是用图形的方式描述哪些子系统是系统自动完成的,哪些是需要人工参与的,并且显示了数据流和控制流。
系统流程图主要描述大的信息系统,这种大的信息系统由单个的子系统和大量的程序块组成。
绘制流程图使用的主要符号如下,也可以有其它的变体。
下面是一个销售系统的流程。
二、结构图及其应用
结构化设计的基本任务,是自顶向下的分解任务,结构图是用来展示计算机程序模块之间的层次关系。
结构图的主要符号如下:
下面是一个工资系统的部分结构图。
三、模块算法设计(伪码)
结构化设计的另一个需求,是描述每个模块的内部逻辑,我们可以用自己熟悉的语言来定义伪码(比如C),使用伪码并不是写出程序,而是为了更清楚地描述模块级的逻辑。
这样也可以避免各种图泛滥成灾。
第三节面向对象的架构设计
在面向对象的设计中,关注点变成了消息和响应机制。
而我们由面向对象的分析转向面向对象的设计是一个自然的结果,在OOA中已经提供了足够多的信息,
在高层设计阶段,我们可以用包图来建立体系架构。
在详细设计阶段,可以利用类图建立相应的体系结构。
下图是以类表达的典型的Nhibernate体系结构。
在设计的各个阶段,在必要的重点位置,我们还可以用顺序图或者协作图来描述一些最重要的消息机制。
面向对象的设计不仅仅是根据功能性和非功能性需求建立一些相应的结构,更重要的是要分析一些潜在问题,通过种种设计技巧,提升系统的整体性能。
下面我们来讨论有关问题。
第四节高层设计中的架构分析
面向对象的设计并不是简单的把需求分析中的领域模型转换成设计模型就可以了,架构师必须在由需求分析获取架构因素,因此我们首先必须研究架构分析的问题。
另外,由于面向对象设计的成熟和发展,已经形成了一系列的重要设计原则和方法,这些原则和方法可以大大的提高我们的设计质量,这是使用OOD必须关注的问题。
面向对象的架构设计与结构化设计根本的不同,是非常注意实时信息,也就是消息和响应机制。
另一方面,也非常注意代码重用,设计的目标往往是大型的、分布式的、可升级、可维护而且是安全的体系,这也对设计者提出了更高的要求。
架构分析的本质,是识别可能影响架构的因素,了解它的易变性和优先级,并解决这些问题。
其难点是,应该了解提出了什么问题,权衡这些问题,并掌握解决影响架构重要因素的众多方法。
架构分析是高优先级和大影响力的活动。
架构分析对如下的工作而言是有价值的:
●降低遗漏系统设计核心部分的风险
●避免对低优先级的问题花费过多的精力
●为业务目标定位产品
一、架构分析
架构分析是在功能性需求过程中,有关识别非功能性需求的活动。
1)架构分析需要解决的问题
下面说明在架构级别上,需要解决的诸多问题的一些示例:
●可靠性和容错性需求是如何影响设计的?
●购买的子组件的许可成本将如何影响收益?
●分布式服务如何影响有关软件质量需求和功能需求的?
●适应性和可配置性是如何影响设计的?
2)架构分析的一般步骤
架构分析有多种方法,大多数方法都是以下步骤的变体。
1.辨识和分析影响架构的非功能性需求。
2.对于那些具有重要影响的需求而言,分析可选方案,并做出处理这些影响的决定,这就是架构决策
二、识别和分析架构因素
1)架构因素
任何需求对一个系统架构都有重要影响。
这些影响包括可靠性、时间表、技能和成本的约束。
比如,在时间紧迫、技能有限同时资金充足的情况下,更好的办法是购买和外包,而不是内部开发所有的组件。
然而,对架构最具影响的的因素,包含功能、可靠性、性能、支持性、实现和接口。
通常是非功能性属性(如可靠性和性能)决定了某个架构的独到之处,而不是功能性需求。
2)质量场景
在架构因素分析期间定义质量需求的时候,推荐应用质量场景。
它定义了可量化(至少是可观测)的响应,并且因此可以验证。
质量场景很少使用模糊的不具度量意义的描述,比如“系统要易于修改”。
质量场景用<激发因素><可量化响应>的形式作简短的描述,如:
●当销售额发送到远程计税服务器计算税金的时候,“大多数”时候必须2秒之内返回。
这一结果是在“平均”负载条件下测量的。
●当系统测试志愿者提交一个错误报告的时候,要在一个工作日内通过电话回复。
这里,“大多数”和“平均”需要软件架构师作进一步的调查和定义。
质量场景直到做到真的可测试的时候,才是真正有效的。
这就意味着需要有一个详细的说明。
3)架构因素的描述
架构分析的一个重要目标,是了解架构因素的影响、优先级和可变性(灵活性以及未来演变的直接需要)。
因此,大多数架构方法,都提倡对以下信息建立一个架构因素表。
因素
测量和质量场景
可变性(当前灵活性和未来演化)
因素(和其变化)对客户的影响,架构和其它因素
获取成功的优先级
困难或风险
可靠性---可恢复性
从远程服务失败中恢复。
当远程服务失败的时候,侦听到远程服务重新在线的一分钟内,重新与之建立联系,在产品环境下实现正常的存储装载。
当前灵活性—我们的SME认为直到重新建立连接前,本地客户简化的服务是可以接受的(也是可取的)。
演化—在2年之内,一些零售商可能选择支付本地完全复制远程服务的功能(如税金计算器)。
可能性?
高。
对大规模设计影响大。
零售商确实不愿意远程服务失败,因为这将限制或阻止它们使用POS进行销售。
高
低
……
……
……
……
注:
SME表示主题专家。
请注意上面的分类方法:
可靠性—可恢复性。
在这里这么说明不等于它是唯一的或者最好的,但它对架构因素的分类很有效。
3)架构因素和UP工件
在架构设计中,中心功能需求库就是用例,它的构想和补充规范,都是创建因素表的重要源泉。
在用例中,特殊需求、技术变化、未决问题应该被反复审核。
其隐含或者清晰的架构因素要被统一整理到补充规范里面去。
例如:
用例1:
ProcessSale
主要成功场景
1.……
特殊需求
●90%的信用授权应该在30秒内响应
●无论如何,当远程服务如库存系统失败的时候,我们需要强健的恢复措施。
●…………
技术和数据变化表
2a.商品的表识可以通过条形码扫描器或者是键盘输入。
…………
未决问题
●税法的变化是什么?
●研究远程服务的恢复问题。
三、架构因素的解析
架构设计的技巧就是根据权衡、相互依赖关系和优先级对架构因素的解决作出合适的选择。
但这还不全面,老练的架构师具有多种领域的知识(例如:
架构样式和模式、技术、产品、缺陷和趋势),并且能把这些知识应用在它们的决定中。
1)记录架构的可选方案、决定和动机
不管目前架构决策的原则有多少,事实上所有的架构方法都推荐记录:
可选的架构方案;决定;影响因素;显著问题;决定动机。
这些记录按不同的的形式或者完善程度,被称之为:
技术备忘录;问题卡;架构途径文档。
技术备忘录的一个重要的的方面就是动机或者原理,当开发者或者架构师以后需要修改系统的时候,架构师可能已经忘了他当初的设计依据(一个资深架构师同时带多个项目的情况非常多见),备忘录对理解当时的设计背后的动机极为有用。
解释放弃被选方案的理由十分重要,在将来产品进化的过程中,架构师也许需要重新考虑这些备选方案,至少知道当初有些什么备选方案,为什么选中了其中之一。
技术备忘录的格式并不重要,关键是简单、清楚、表达信息完整。
技术备忘录
问题:
可靠性---从远程服务故障中恢复
解决方案概要:
通过使用查询服务实现位置透明,实现从远程到本地的故障恢复和本地服务的部分复制
架构因素
●从远程服务中可靠恢复
●从远程产品数据库的故障中可靠恢复
解决方案
在服务工厂创建一个适配器……
动机
零售商不想停止零售活动……
遗留问题
无
考虑过的备选方案
与远程服务厂商签订“黄金级”服务协议……
2)优先级
下面是指导做出架构决定目标:
1.不可改变的约束,包括安全和法律方面的事务
2.业务目标
3.其它全部目标
早期要决定是否应该避免保证未来的设计,应该实事求是的考虑,那些将要推迟到未来的场景,有多少代码需要改变?
工作量将是多少?
仔细考虑潜在的变更将有助于揭示什么是首要考虑的重要问题。
一个低耦合高内聚的产品,往往比较容易适应将来的变化,但也要仔细分析这样付出的代价,在这个问题上,架构师的掂量往往是决定这个项目的生命线。
3)系统不同方面的分离和影响的局部化
架构分析的另外一个基本原则,就是实现分离系统的不同方向。
系统不同方向的分离,是在架构级别上关于低耦合和高内聚的一种大尺度思考方法。
虽然它们也应用在小尺度对象上,但这样的分离对于架构问题尤其突出。
因为系统的不同方面很广泛,而且架构的解决方案涉及重要的设计选择。
至少有三个实现系统不同方面分离的大尺度技术:
1.把系统的一个方面模块化到一个独立的组件(如子系统)中并且调用它的服务。
2.使用装饰器模式
3.采用后编译器技术和面向方面的技术
有了架构分析的结果,我们就可以讨论高层架构设计本身的一系列原则了。
第五节高层架构设计中的层模式
一、面向对象软件架构的优点
1)面向对象软件架构的维和视图
一个系统的架构包括了多个维。
例如:
●逻辑架构:
描述系统的层、包、主要框架、类、接口和子系统的概念组织方式。
●部署架构:
描述系统的进程如何分配给处理单元和网络配置。
统一过程建议采用架构的六种视图(逻辑、部署等),我们后面会讨论这个问题。
2)架构模式和模式的种类
架构模式是有关大尺度和粗粒度的设计,特别是应用在早期迭代过程(细化阶段)。
也就是当主要的结构和连接建立起来的时候的一些原则。
l
二、层模式
1)解决方案:
层模式(Layerspattern)的基本思想很简单。
●根据分离系统的多个具有清晰、内聚职责的设计原则,把系统大尺度的逻辑结构组织到不同的层中,每一层都具有独立和相关的职责,使得较低的层为低级和通用的服务,较高的层更多的为特定应用。
●从较高的层到较低的层进行协作和耦合,避免从底层到高层的耦合。
层是一个大尺度的元素,通常由一些包或者子系统组装而成。
层模式与逻辑架构相关,也就是说,它描述了设计元素概念上的组织,但不是它物理上的包或者部署。
层为逻辑架构定义了一个N层模型,称之为分层架构(LayersArchitecture),它作为模式得到了极为广泛的应用和引述。
框架(framework):
一般来说框架具有如下的特征:
●是内聚的类和接口的集合,它们协作提供了一个逻辑子系统的核心和不变部分的服务。
●包含了某些特定的抽象类,它们定义了需要遵循的接口。
●通常需要用户定义已经存在的框架类的子类,是客户得以扩展框架的服务。
●所包含的抽象类可能同时包含抽象方法和实例方法。
●遵循好莱坞原则:
“别找我们,我们会找你。
”就是用户定义得类将从预定义的类中接受消息,这通常通过实现超类的抽象方法来实现。
2)问题:
●由于系统的许多部分高度的耦合,因此源代码的变化将波及整个系统。
●由于应用逻辑与用户接口捆绑在一起,因此这些应用逻辑在其它不同的接口上无法重用,也无法分布到另一个处理节点上。
●由于潜在的通用技术服务或业务逻辑,与更具体的应用逻辑捆绑在一起,因此这些通用技术服务或者业务逻辑无法被重用,或者分布到其它的节点,或者被不同的实现简单的替换。
●由于系统的不同部分高度的耦合,因此难以对不同开发者清晰界定格子的工作界限。
●由于高度耦合混合了系统的各个方面,因此改进应用程序的功能,扩展系统,以及使用新技术进行升级往往是艰苦和代价高昂的。
3)示例:
信息系统一般分层逻辑架构。
在具体架构设计的时候,可以建立比较详细的包图,但是,并不需要面面俱到。
架构视图的核心,是展示少数值得注意的元素。
统一过程的架构视图是这样告诫的:
“选择一小组有意义的元素来传达主要的思想。
”
特别注意:
在面向对象的层模式中,底层的类不仅仅提供调用,更主要的是提供父类,很多情况下,需要使用配置文件来动态装配,这样才能适应不同的需求。
4)层与层之间和包与包之间的耦合
逻辑架构还可以包含更多的信息,用来描述层与层以及包与包之间值得注意的耦合关系。
在这里,可以用依赖关系表达耦合,但并不是确切的依赖关系,而仅仅是强调一般的依赖关系。
有时候也可以不画出类,专注于包之间的依赖关系。
5)协作:
在架构层面上,有两个设计上的决策:
1.什么是系统的重要部分?
2.它们是如何连接的?
在架构上,层模式对定义系统的重要部分给出了指导。
象外观、控制器、观察者这些模式,通常用于设计层与层、包与包之间的连接。
6)外观模式
GoF的外观模式,定义了一个公共的外观对象综合子系统的服务。
外观不应该表示大量子系统的操作,更确切的说,外观更适合表示少量的高层操作、粗粒度的服务。
当外观呈现大量的底层操作的时候,会趋向于变得没有内聚力。
外观模式为了一组子系统提供一个一致的方式对外交互。
这样就可以使客户和子系统绝缘,可以大大减少客户处理对象的数目,注意下图。
使用Facade之前
使用Facade之后
这样本来一个类的修改可能会影响一大片代码,而加了外观类以后只需要修改很少量的代码就可以了,使系统的高级维护成为可能。
7)通过观察者实现向上协作
外观模式通常用于高层到底层的操作(底层提供外观,高层实现调用)。
当需要上层对底层的操作的时候,可以使用观察者模式。
也就是上层响应底层的事件,但这个事件的执行代码由上层提供。
8)层之间的松散耦合
大部分的多层架构不能像基于OSI7层模型的网络协议一样,上一层只能调用下一层。
相反,在信息系统中的分层通常是“松散的分层”或者说是“透明的分层”。
一个层的元素可以和多个其它层的元素协作或耦合。
对于一般层之间耦合的观点是:
●所有较高的层都可以依赖于技术服务层和基础层
比如在Java中,所有的层都依赖于java.util包元素。
●依赖于业务基础设施层的领域层是要首先考虑的。
●表示层发出对应用层的调用,应用层再对领域层进行服务调用。
除非不存在应用层,表示层一般是不直接对领域层进行调用的。
●如果应用是一个单进程的“桌面”程序,那么领域层的软件对象对于表示层、应用层和更底层(如技术服务层)可以直接可见或者在中间传递。
●另一方面,对于一个分布式系统,那么领域层对象的可序列化复制对象(通常称之为值对象或者数据容纳对象)通常可以被传递到表示层。
在这种情况下,领域层被部署到另一台服务器上,客户端节点得到服务器数据的拷贝。
现在的问题是,与技术服务层和基础层的关系不是很危险吗?
正如GRASP的受保护变化模式和低耦合模式的论述,耦合本身并不是个问题,但是与变化点和演化点的耦合是不稳定的而且是难于修正的。
几乎没有任何理由,去抽象和隐蔽某些不太可能变化的因素,即使这些因素可能变化,这种变化所产生的影响也是微乎其微的。
例如,建立一个Java应用程序,隐蔽对Java类库的访问有什么意义呢?
与类库的多个紧密耦合不太可能是个问题,因为它们是相对稳定而且无处不在的。
9)应用层是可选的吗
如果存在应用层,那么它所包含的对象要负责了解客户端的会话状态,协调表示层和领域层,以及控制工作流。
10)在不同的层上模糊集合成员
一些元素必定只属于一个层,但有些元素却难以区分,特别是处在技术服务层和基础层之间,或者领域层和业务基础设施层之间的元素。
其实这些层之间只存在模糊的差异,所以,“高层”、“低层”、“特殊”、“一般”这些术语是可以接受的。
开发组并不需要在限定的分类上做出决定,可以粗略的把一个元素归类到技术服务层或者基础层,也可以称之为“基础设施层”,注意,对于层并没有十分确定的命名习惯和约定,文献上各种命名上的矛盾是常见的,研究问题主要把握精髓,不要被这些表面的区别搞昏了头。
11)使用反射动态装入对象
不论是Java还是.NET,都很好的支持了反射,这样,建立一种通用对象容器成为可能,在详细设计的讨论中,我们会讨论一个这样的例子。
12)利用工厂模式构建通用的创建者
为了保证层的通用型,在层中的必要部分,可以采用工厂模式创建对象,这个问题我们也会在详细设计的讨论中加以阐述。
13)层模式的优点:
●层模式可以分离系统不同方面的考虑,这样就减少了系统的耦合和依赖,提高了内聚性,增加了潜在的重用性,并且增加了系统设计上的清晰度。
●封装和分解了相关的复杂性。
●一些层的实现可以被新的实现替代,一般来说,技术服务层或者基础层这些比较低层的层不能替换,而表示层、应用层和领域层可能进行替换。
●较低的层包含了可重用的功能。
●一些层可能是分布式的(主要是领域层和技术服务层)。
●由于逻辑上划分比较清楚,有助于多个小组开发。
三、模型-视图分离原则
这个原则我们已经讨论了多次,但这里还是有必要总结一下。
非窗口类如何与窗口类通信?
推荐的做法,是其它组件不和窗口对象直接耦合。
因为窗口和特定的应用有关,耦合太强不利于重用。
这就是模型--视图分离的原则。
模型—视图分离(Model–ViewSeparation)的原则,已经发展为模型-视图-控制器(Model-View-ControllerMVC)模式的一个关键原则。
MVC起源于一个小规模的Web架构(比如Struts),近来,这个术语(MVC)被分布式设计团体采纳,也应用在大规模的架构上,模型指领域层,视图指表示层,控制器指应用层的工作流对象。
模型—视图分离原则的动机包括:
●为关注领域处理而不是用户界面而定义内聚的模型。
●允许分离模型和用户界面层的开发。
●最小化界面因为需求变更给领域层带来的影响。
●允许新的视图方便的连接到领域层而不影响领域层。
●允许在同一模型对象上有多个联立的视图。
●允许模型层的运行独立于用户界面层。
●允许方便的把模型层简单的连接到另一个用户界面框架上。
第六节框架设计的方法学问题
一、框架(Framework)的基本概念
事实已经表明,一个软件组织,合理的组织开发和使用框架,并且能跨越组织边界进行合作的能力越来越重要。
软件架构使得您能够组合大量支撑产品和服务,一个共享的架构,可以使企业开发团队很方便的分解问题,从而确定:
哪些可以企业(或者开发组)内部解决;
哪些可以使用已有的服务。
当架构跨越组织的时候,你就可以调选公司内外组织的合作力量,获得共享架构带来的好处,在这样的情况下,架构设计组或者整个公司都需要掌握一些新的组织技能。
当公司内部存在产品线的时候,设计优秀的共享架构都可以带来实实在在的好处。
(1)框架
框架最简单的形式是指已开发过并已测试过的软件的程序块,这些程序块可以在多个软件开发工程中重用。
框架提供了一个概括的体系结构模版,可以用这个模板来构建特定领域中的应用程序。
(2)为什么会出现应用框架
您只要细心地研究真实的应用程序,就会发现程序大致上由两类性质不同的组件组成,一类与程序要处理的具体事务密切相关,我们不妨把它们叫做业务组件;另一类是应用服务。
人们自然会想要是把这些在不同应用程序中有共性的一些东西抽取出来,做成一个半成品程序,这样的半成品就是所谓的程序框架,再做一个新的东西时就不必白手起家,而是可以在这个基础上开始搭建。
实际上,大型软件企业往往选择搭建自己的框架。
(3)为什么要用框架?
因为软件系统发展到今天已经很复杂了,特别是服务器端软件,设计到的知识,内容,问题太多。
在某些方面使用别人成熟的框架,就相当于让别人帮你完成一些基础工作,你只需要集中精力完成系统的业务逻辑设计。
而且框架一般是成熟,稳健的,他可以处理系统很多细节问题,比如,事物处理,安全性,数据流控制等问题。
还有框架一般都经过很多人使用,所以结构很好,所以扩展性也很好,而且它是不断升级的,你可以直接享受别人升级代码带来的好处。
目前一些常用的开源框架如下:
Web层
二、框架设计的核心原则
五个核心原则:
构想、预见、节奏、协作和简化。
1)构想
构想原则说明了如何向架构的受益人描绘一幅一致的、有约束力的、以及灵活的未来图像。
作为架构师,关键是要确保它提出来的架构设想与公司的业务目标相吻合,对于一个大型公司,做到这点事实上并不容易。
再次提醒,面向对象的架构,关键不是调用,而是继承和重用。
2)节奏
节奏原则确保软件组织可以定期根据可预测的速度、内容和质量对工件进行取舍。
在新颖的性能和规定的发布日期之间,有时候必须进行取舍,以确保发布日期,但这点可能和公司高层的设想不同,这如何解决呢?
3)预见
首席架构师必须对未来发展走向有敏锐的洞察力,但这种预见往往和现行的标准有冲突,这就需要在两者间做出平衡,而这种平衡也是非常难处理的。
4)协作
当首席架构师开始架构设计的时候,协作显得及其重要,我们一定要确保公司、周边合作者、领域架构师和开发组都能理解架构的关键思想,
5)简化
简化原则要求澄清并最小化架构与创建,当发现两个小组开发的构件有重叠的部分以后,应该可以考虑指定一个共享的构件,如何实现简化是构架师最值得关注的一个问题,非此架构设计的意义就显得不大。