架构讲义4

来源:互联网 发布:怎么清空手机所有数据 编辑:程序博客网 时间:2024/04/25 15:49
 
第四章 高层软件架构的设计
 
在高层设计阶段,主要工作是分析与设计软件的体系结构。通过系统分解,确定子系统的功能和子系统之间的关系,以及模块的功能和模块之间的关系,产生《体系结构设计报告》。
       这个阶段是系统架构师发挥作用的主要位置,高层架构设计过程设计流程如下。

设计
 准备
撰写
 文档
设计
评审
确定
 约束
 因素
确定
设计
策略
系统
分解
设计
 

 

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

 Struts / WebWork / Tapestry / Spring MVC
Web
 Spring(轻量级容器)
Spring框架的主要内容
1)核心概念
      依赖注入--轻量级容器(应用上下文)
      AOP --声明性企业级服务(如事务)
2)持久化:JDBC封装、与其它开源实现的整合
3Spring MVC
4)远程调用、EJB服务的替代方案
 Hibernate / ibatis / JDO
业务层
数据层(持久层)

 
    二、框架设计的核心原则
 
    五个核心原则:
    构想、预见、节奏、协作和简化。
 
    1)构想
构想原则说明了如何向架构的受益人描绘一幅一致的、有约束力的、以及灵活的未来图像。作为架构师,关键是要确保它提出来的架构设想与公司的业务目标相吻合,对于一个大型公司,做到这点事实上并不容易。
再次提醒,面向对象的架构,关键不是调用,而是继承和重用。
 
    2)节奏
    节奏原则确保软件组织可以定期根据可预测的速度、内容和质量对工件进行取舍。在新颖的性能和规定的发布日期之间,有时候必须进行取舍,以确保发布日期,但这点可能和公司高层的设想不同,这如何解决呢?
 
    3)预见
    首席架构师必须对未来发展走向有敏锐的洞察力,但这种预见往往和现行的标准有冲突,这就需要在两者间做出平衡,而这种平衡也是非常难处理的。
 
    4)协作
    当首席架构师开始架构设计的时候,协作显得及其重要,我们一定要确保公司、周边合作者、领域架构师和开发组都能理解架构的关键思想,
 
    5)简化
    简化原则要求澄清并最小化架构与创建,当发现两个小组开发的构件有重叠的部分以后,应该可以考虑指定一个共享的构件,如何实现简化是构架师最值得关注的一个问题,非此架构设计的意义就显得不大。
 
    这五个原则被称之为VRASP模型(Vision、Rhythm、Anticipation、Partnering、 Simplification)。这个模型重点在于软件架构的组织方面,事实上,软件架构师得以成功的最大障碍是组织问题而不是技术问题。
 
    三、形成构想
 
    1)把价值映射为架构约束
 
这个问题的本质,是架构受益人如何把客户价值与架构约束捆绑。这里所谓受益人,实际上是指使用架构的开发者。

用户价值
共享架构
受益人
受益人
用户价值

一致性和灵活性的考虑:
一致性的问题:是指受益人使用架构与期望值的符合程度。
灵活性的问题:是指受益人不破坏架构的情况下,利用共享框架的创建新的没有预见到的情况下的容易程度。
 
2)产品线及其挑战
 
当产品线上有多个产品的时候,为了避免架构的设计被被动的拉向不同的方向,可以使用下面的三步方法:
1,清楚、简明的、阐述一条迫切的用户价值。
    2,把用户价值映射为少数的能解决的问题。
3,把以上问题转译为一组最小的约束条件。
遵循准则:
1,各方面的一致性
2,实施人员信任并使用架构
3,架构潜藏的知识对用户是可识别和可获得的
 
四、保证节奏
 
节奏能够克服复杂性,确保竞争优势。
节奏有三个元素:速度、内容和质量。
速度:一个团队和另一个团队之间(架构团队和开发工程师团队之间)同类型交接发生的频率,每次交接的时间越是可预测的,移交也就越容易管理。
内容:内容是指一个团体向另一个团体提供的价值。当软件架构师向开发团队提交的构架使开发团队获得了实实在在的好处,这个架构就被认为是有价值的。
质量:质量的含义是开发过程确保架构没有缺陷。
遵循准则:
1,经理们需要定期评估、同步和调整架构
2,架构用户需要对架构发布的内容和进度有高度的信心
3,通过节奏协调明确的活动
 
    五、预测、验证和调整
 
架构师可以通过自己的经验和成功使用的架构,合理的猜测将来会发生什么。例如:
    用户会有什么变化?
    竞争形势会如何改变?
    运行环境会如何改变?
    架构的设计必须是能够适应这种可能的变化。
 
    1)验证:
    在架构设计中,验证主要指的是对架构基础假定的测试,在架构成型以前,除非通过测试当初的基础假定是被确认的,否则就会发生代价高昂的错误。
 
    2)调整:
    当预测结果发生变化的时候,你所面临的问题就是调整。
 
    六、实现协作
 
    在软件架构环境中,协作主要涉及对受益人的关系进行管理的过程。
   
    合作并不能保证架构的受益人总是能和您保持一致,但是,当架构供应者发现他们有哪些功能他们没有一致的理解的时候,就必须用达成一致的方法来解决这个矛盾。
    架构设计者应该和所有的架构受益人合作,使利益最大化,而不是仅仅靠合同和协议过日子。
    注意价值链的概念,每个行业都有自己的价值链,成功的构架设计者应该关注这些价值链。
    几个准则:
    1,架构师需要了解谁是关键受益人,他们如何贡献价值,以及他们需要贡献什么。
    2,和受益人之间达成明确和强制性的契约。
    3,通过制度和非正式的规范强化合作。
 
    七、简化
 
    架构师和高级经理应该协力保持架构的平衡。
当某个新产品加入的时候,会大大增加架构的体积。架构师应该关注通用的服务,某个客户专用的能力不应该放入通用的架构里面。
架构师应该仔细考虑,极力找出隐蔽在多个不同需求中的公共元素。对于不能放弃的大型客户,需要仔细的谈判,提出多种解决方案供用户选择,而不是简单的行或者不行。
    准则:
    1,开发人员长期不断的使用架构的时候,减少了总成本和复杂性。
    2,架构师明确理解关键最小需求,并构造多应用共享核心单元。
    3,当不能被共享或者增加了不必要的复杂性的时候,应该把相关元素从核心移走。
在一个善于简化的组织中,开发人员会不断地清理核心,因为人人都知道复杂的核心所带来的麻烦。
 
第七节 面向服务架构(SOA
  
面向服务的架构 (Service-Oriented Architecture SOA)是一种形式化的分离服务的架构风格。
面向服务的架构关注的是哪些是服务向用户提供的功能,哪些是需要这些功能的系统,这种分离,使用一种服务合约(Service Contract)的机制来完成的。
本质上来说,SOA体现的是一种新的系统架构,SOA的出现,将为整个企业级软件架构设计带来巨大的影响。
 
一、SOA的优点
 
SOA框架的特点是以服务为中心,它把应用程序划分成具有明确定义接口的模块,从而得到服务和应用程序之间相当松散的耦合。
在SOA中,服务供应商和消费者是两个独立的实体。
面向服务的架构的优点主要体现在以下几个方面:
l         降低应用开发费用。
l         降低维护费用。
l         增长的公司敏捷性。
l         生成对应用程序和设备的故障、中断更具免疫力的系统,提高整体的可靠性。
l         提供了一条应用系统的升级途径,对比使用单一的应用程序的时候,需要替换整个应用系统的标准升级方法,显然更为经济,更不容易失败。
 
二、SOA的特性
 
SOA 有以下特性:
l         服务具有明确的接口(合约)与策略。
l         服务通常代表业务功能或者领域。
l         服务拥有模块化的设计。
l         服务被松散的耦合在一起。
l         服务是可以被发现的。
l         服务的位置对客户是透明的。
l         服务是独立于传输层的。
l         服务是独立于平台的。
SOA可以通过很多方式来实现,但最常用的SOA是用Web Service来实现,这主要应为Web Service的独立于平台的特性和其它特性更符合SOA 的规则。
 
1)服务具有明确的接口与策略
 
明确定义服务具有的接口(合约)是SOA 的核心定义。
合约应该包含两部分内容,一个是接口,另一个是业务策略。
普通对象概念的接口包括:
l         数据类型。
l         期望的输出。
l         必需的输入。
l         错误信息。
SOA的合约扩大了接口的概念,包括:
l         所提供的功能。
l         需要的输入和期望的输出。
先决条件。
l         后置条件。
l         错误处理。
l         服务品质保证等。
关于业务策略,事实上服务的生产者和消费者都要定义策略,包括可靠性、可用性、安全性等等。
1.所提供的功能
确切说明服务允许完成什么。
2,期望的输入和输出
服务期待什么样的输入以及它能提供什么样的输出,对客户来说这是一个重要的信息。
3,先决和后置条件
先决条件:
服务激活前存在的输入或者应用程序的状态,最常见的输入是安全口令。
后置条件:
请求被处理以后服务的状态。比如服务作为某个事物的一部分来调用的,这时候服务必须接到事务协调者的通知后才能完成这个事物的提交。
服务如何应对错误是绝对的后置条件,系统出错以后不同的错误系统应该是什么状态,这点必须写清楚。
 
4,错误处理
错误处理是另外一个需要在合约中说明的领域,从UML的观点来看,错误是一个通道,所有错误都不返回参与者所期望的价值产品。
客户需要知道描述错误的数据结构或者其它信息。
5,服务品质协议
服务品质(QoS)是可选的,但确是合约的重要组成部分,因为消费者很大程度上可以根据提供者提供的服务水准,来选择它们的提供者。
服务品质包括诸如:性能、多线程、容错之类问题。
6,注册表
注册表(Registry)把所有的东西联系到了一起,它是服务保存信息和登记信息的地方,也是消费者找寻和履行合同的地方。
注册表这个术语有很多意思。一个注册表可以为消费者提供一个指定的查询标准,来查找合约的机制。然后消费者将和服务联接在一起。
注册表可以由企业、独立来源、或者需要提供服务的其它业务组织来维护和提供,所有的注册表都需要实现允许独立登记,让消费者查找服务提供者并且和它们连接的应用程序编程接口(API)。
注册表是把消费者和服务方分离开来的核心机制,这种分离允许SOA增加需求能力,并且提供连续可用的服务。
注册表并不一定需要包含合约,注册表可以包括提供者所提供的服务以及合约地点的描述信息,这样可以允许提供者在本地维护自己的合约,这样也可能更加方便。
 
2)服务代表业务领域
服务可以用来建立各种各样的问题的领域,即可以是企业领域,也可以是技术领域。
SOA真正的能力,在与可以为企业领域建模,因为业务服务通常比技术服务更加难以实现,无论对内和对外都更加有价值,所以SOA真正持久的价值在于建立一个重要业务过程的服务。
 
3)服务拥有模块化设计
服务由模块组成,模块花设计对SOA来说是很重要的,模块可以被看作是一个执行具体、明确功能的软件和子系统。
模块应该表现为高的内聚性,而且是完整的功能。
粗粒度做法是构造一个完整的转账模块,这种模块提升了系统性能,但减少了可重用性。但是,SOA通过网络实现服务,网络拥挤可能是主要矛盾,因此,SOA推荐的是粗粒度设计。这点非常重要。
 
4)服务应该松散耦合
服务客户和服务提供者之间应该实现松散耦合,也就是客户和提供者之间没有静态的、编译时刻的依赖关系。
服务把它履行职责的细节隐蔽起来。
这种隐蔽,几乎大部分资料都是建议主要通过GoF 的外观模式(Facade)实现。
 
5)服务应该是可以被发现并且支持内省的
SOA的灵活性和可复用性另外一个关键点,就是动态发现和绑定的概念。
服务和客户之间没有任何静态连接,SOA客户通过注册表来查找它们想要的功能,而不是使用编译的时候静态连接。因此,服务和客户都可以自由修改。
服务还可以在一个有限的时间内被提供,这就是说它们可以被租借,当客户超过有效时间以后,将会被迫转回到注册表,重新绑定合约或者选择另外的合约。
 
6)服务是独立于传输机制的
客户使用网络来访问和使用服务,SOA 应该独立于访问服务的网络种类,服务独立于用来访问他的传输机制,意味着需要建立一个适配器来支持访问它的各种传输机制。通常情况下,适配器需要根据情况来构造(HTTP或者RMI),同一个适配器,也可以被多个服务所使用。
 
7)服务的位置对客户是透明的
服务的位置对客户透明,实施上表达了客户调用服务的时候,并不需要关心服务具体的位置。这就使SOA在实现过程具有巨大的灵活性。服务可以被放到最方便的地方去,必要的时候(比如企业整顿),服务业可以放到第三方提供者那里。或者服务中断的时候,可以把服务请求转发到完全不同的另一个地点。
 
8)服务应该是独立于平台的
服务应该独立于平台和操作系统。
对于Web 服务来说,虽然在理论上,Java和.NET使用着相同的协议和标准,因此,进行互操作是没有问题的,但实际上,由于SOAP、协议中有很多模糊和未定义部分,所以,这之间的互操作还是存在不少问题,需要我们认真加以研究和试验。
 
三、构建SOA架构时应该注意的问题
 
当架构师基于SOA来构建一个企业级的系统架构的时候,一定要注意对原有系统架构中的集成需求进行细致的分析和整理。基于SOA的企业系统架构通常都是在现有系统架构投资的基础上发展起来的,我们并不需要彻底重新开发全部的子系统。
SOA可以通过利用当前系统已有的资源(开发人员、软件语言、硬件平台、数据库和应用程序)来重复利用系统中现有的系统和资源。SOA是一种可适应的、灵活的体系结构类型,基于SOA构建的系统架构可以在系统的开发和维护中缩短产品上市时间,因而可以降低企业系统开发的成本和风险。
 
四、服务粒度的控制
 
当SOA架构师构建一个企业级的SOA系统架构的时候,关于系统中最重要的元素,也就是SOA系统中的服务的构建有一点需要特别注意的地方,就是对于服务粒度的控制。
服务粒度的控制SOA系统中的服务粒度的控制是一项十分重要的设计任务。通常来说,对于将暴露在整个系统外部的服务推荐使用粗粒度的接口,而相对较细粒度的服务接口通常用于企业系统架构的内部。
 
 
 
 
五、案例:电源销售服务系统高层架构
 
这里只列出了初步的顶层架构。
 
 
设计中注意了几个问题:
1,对于管理层和客户,主要从使用方便性考虑,采用浏览器。
2,对于工作人员,因为要处理的内容比较复杂,采用应用程序,但是一个免维护的瘦客户端。
3,瘦客户段并不是指代码越少越好或者功能越少越好,而是把易变的、需要配置的、需要集中处理的内容转向应用程序服务器。事实上,客户端的功能越强,越能缓解服务器的压力。
4,某些特殊的专业通讯联系(比如信用卡授权机构),可以由客户段直接完成,并不一定一切都通过服务器,但需要向服务器提交必要的信息。
5,对于集中处理的部分,采用大粒度设计,以缓解网络压力。
6,由于服务方采用无状态模式,所以要严格控制客户调用信息的时间,对于需要长时间传输的信息,可以采用其它通道完成。
7,对于客户应用程序,某些不是十分大的,变化频度不是十分高的,调用频度比较高的数据,可以在客户端建立缓存,并且可以建立关联的映像表,这样就可以对避免对最主要的数据处理的挤压,提高数据库的应用效率,但要考虑修改数据时候的并发策略。
 
第八节 软件架构的质量描述和评估
 
一、软件架构的创建原则
 
每个项目最开始的时候,是构架师最重要的时刻,在创建架构的过程中,可以依照下面的原则:
架构应该是精炼的;
架构应该是平易近人的;
架构应该是易读的;
架构应该是容易理解的;
架构应该是可信的;
架构不一定要是完美无缺的;
不一定要一开始就做大的设计,如果在模型完善和实现之间作个选择的话,选择实现它;
做最简单和可行的事情,不要排除未来的需求;
架构是共享的财产;
让所有的涉众都参加进来,但还要能控制局面;
架构组的规模应该小;
 
软件架构需要做的事情是:
理解需求:
特别是非功能性需求,或者叫品质需求。
创建或者选择架构:
尽可能使用架构师熟悉的方法、技术和实践来满足,使用不为人所知的方法来创建架构是要冒一定风险的。
为了识别好的架构方案,可以采用下面的检查列表,作为可能误入岐途的早期预警征兆:
 
1)架构被迫要求满足当前组织习惯。
当软件组织的习惯与需求不一致的时候,被迫满足组织的习惯,很容易误入岐途,很多情况下,适当的妥协是可以的,但架构的完整性应该尽可能保持。
 
2)有太多的最高层架构组件(复杂性太高)。
如果这些组件的数目达到一定的级别(一般为25个),架构就已经太复杂了,以至于无法保证项目本身概念的完整性。
 
3)某个特定需求超过了设计中的其它需求。
当某个目标高于其它一切需求的时候,那就要考虑这个目标可能只是投资商、项目经理、甚至是构架师的偏好,某个需求高于一切的时候,往往不能兼顾其它的需求。
 
4)架构依赖于平台提供的选择。
实际上一个高度易用性的项目是不能受平台制约的。
 
5)使用某些专用的组件,而不使用同样好的标准组件。
不要被花哨的设计和有趣的设计所迷惑,有很多能力可以使用标准组件来完成的。
 
6)组件的定义划分来自于硬件的划分。
组件的设计过程是不考虑硬件结构的,否则软件就缺乏拓展性。
 
二、品质属性
 
软件架构的品质属性,可以通过下面几个方面来描述,请试试能不能定量的描述。
 
1)性能
每个用例的预期响应时间是多少。
平均/最慢/最快的预期响应时间是多少。
需要使用哪些资源(CPU,局域网等)。
需要消耗多少资源。
使用什么样的资源分配策略。
预期的并行进程有多少个。
有没有特别耗时的计算过程。
服务器是单线程还是多线程。
有没有多个线程同时访问共享资源的问题,如果有,如何来管理。
不好的性能会在多大程度上影响易用性。
响应时间是同步的还是异步的。
系统在一天、一周或者一个月,系统性能变化是怎样的。
预期的系统负载增长是怎样的。
 
2)可用性
系统故障有多大的影响。
如何识别是硬件故障还是软件故障。
系统发生故障后,能多快恢复。
在故障情况下,有没有备用系统可以接管。
如何才能知道,所有的关键功能已经被复制了呢。
如何进行备份,备份和恢复系统需要多长时间。
预期的正常工作时间是多少小时。
每个月预期的正常工作时间是多少。
 
3)可靠性
软件或者硬件故障的影响是什么。
软件性能不好会影响可靠性吗。
不可靠的性能对业务有多大影响。
数据完整性会受到影响吗。
 
4)功能
系统满足用户提出的所有功能需求了吗。
系统如何应付和适应非预期的需求。
 
5)易用性
用户界面容易理解吗。
界面需要满足残疾人的需求吗。
开发人员觉得用来开发的工具是易用的和易理解的吗。
 
6)可移植性
如果使用专用开发平台的话,用它的优点真的比缺点多吗。
建立一个独立层次的开销值得吗。
系统的可移植性应该在哪一级别来提供呢(应用程序、应用服务器、操作系统还是硬件级别)。
 
7)可重用性
该系统是一系列的产品线的开始吗。
其它建造的系统有多少和现有系统有关呢?如果有,其他系统能重用吗。
哪些现有组件是可以重用的。
现有的框架和其它代码能够被重用吗。
其它应用程序可以使用这个系统的基础设施吗。
建立可重用的的组件,代价、风险、好处是什么。
 
8)集成性
于其它系统进行通信的技术是基于现行的标准吗。
组件的接口是一致的和容易理解的吗。
有解释组件接口的过程吗。
 
9)可测试性
有可以测试语言类、组件和服务的工具、过程和技术吗。
框架中有可以进行单元测试的接口吗。
有自动测试工具可以用吗。
系统可以在测试器中运行吗。
 
10)可分解性
系统是模块化的吗。
系统之间有序多依赖关系吗。
对一个模块的修改会影响其它模块吗。
 
11)概念完整性
人们理解这个架构吗。是不是有人问很多很基本的问题呢。
架构中有没有自相矛盾的决策。
新的需求很容易加到架构中来吗。
 
12)可完成性
有足够的时间、金钱和资源来建立架构基准和整个项目吗。
架构是不是太复杂。
架构足够的模块化来支持并行开发吗。
是不是有太多的技术风险呢。
 
上述问题,给我们提供了一个线索,在回答这些问题的时候,我们对初始设计的改进方向,就已经一目了然了。
 
 
原创粉丝点击