关于ESB

ESB 浮火了一阵子(貌似现在还在浮火),那段时间研究了Servermix和Mule,真的是很痛苦!说起来都好听,用起来很憋屈!我的话就是--去TMD。

目前整理一下:

http://baike.baidu.com/view/1224042.htm 

一、ESB的五个基本功能

          1)服务的MetaData管理:在总线范畴内对服务的注册命名及寻址进行管理。

2)传输服务:确保通过企业总线互连的业务流程间的消息的正确交付,还包括基于内容的路由功能。

3)中介:提供位置透明的路由和定位服务;提供多种消息传递形式;支持广泛使用的传输协议。

4)多服务集成方式: 如JCA,Web服务,Messaging ,Adaptor等.

5)服务和事件管理支持: 调用服务的记录、测量和监控数据;提供事件检测、触发和分布功能;

二、ESB的八个扩展功能:

1) 面向服务的元数据管理: 他必须了解被他中介的两端,即服务的请求以及请求者对服务的要求,以及服务的提供者和他所提供的服务的描述;

2) Mediation :它必须具有某种机制能够完成中介的作用,如协议转换;

3) 通信:服务发布、订阅,响应 请求,同步异步消息,路由和寻址等;

4) 集成: 遗留系统适配器,服务编排和映射,协议转换,数据变换,企业应用集成中间件的连续等。

5) 服务交互: 服务接口定义,服务实现的置换,服务消息模型,服务目录和发现等。

6) 服务安全: 认证和授权、不可否认和机密性、安全标准的支持等;

7) 服务质量: 事务,服务的可交付性等;

8) 服务等级: 性能、可用性等。

ESB 中最常提到的两个功能是消息转换和消息路由,也可说 消息路由,消息转换,协议转换,消息增强。

http://blogger.org.cn/blog/more.asp?name=lhwork&id=17123

[ESB]目前三个主流的开源ESB项目简介

一个是Object Web的Celtix:它原来是一个商业软件,因为卖的不好,所以转到OW下面,想增加一点知名度。

第二个是codehaus的ServiceMix :它是真正意义上的兼容JSR208 JBI标准的ESB容器。它的主要特性包含:

  1. JBI 容器 SOA在Java领域有两套标准:一个是SUN推出的JBI(没有得到BEA和IBM的承认),另外一个是:IBM和BEA等公司推出的SCA和SDO标准
  2. 脚本支持
  3. 规则引擎 
  4. 工作流引擎
  5. BPEL 引擎  [业务过程执行语言,是一种基于XML的,用来描写业务过程的编程语言,被描写的业务过程的每个单一步骤则由Web服务来实现。]
  6. Web Services Notification 实现

天,把这么多怪物结合在一起,那连怪物也算不上了!Servermix还赶不上mule,牛谁都会吹!哪点那做好了?

第三个是codehaus的Mule :Mule不算真正意义上的JBI实现。它更像是一个对象代理。但是因为它先走一步,所以已经非常成熟。它对EIP 企业应用集成提供了一套完整的支持。另外他也提供了JBI的接口。

从应用角度来说,如果你现在要做企业应用集成的项目,Mule是可以最快上手的项目。

Mule和ServiceMix都支持Spring,Pico作为组件容器的容器。

照上面第二点,规则引擎,工作流,SOA与ESB的功能打上边也不足为奇了!

Continue reading 关于ESB

【转】试论软件的可靠性及其保证

http://www.csai.cn 作者:张振华 2004年10月20日

用软件系统规模越做越大越复杂,其可靠性越来越难保证。应用本身对系统运行的可靠性要求越来越高,在一些关键的应用领域,如航空、航天等,其可靠性要求尤为重要,在银行等服务性行业,其软件系统的可靠性也直接关系到自身的声誉和生存发展竞争能力。
特别是软件可靠性比硬件可靠性更难保证,会严重影响整个系统的可靠性。在许多项目开发过程中,对可靠性没有提出明确的要求,开发商(部门)也不在可靠性方面花更多的精力,往往只注重速度、结果的正确性和用户界面的友好性等,而忽略了可靠性。在投入使用后才发现大量可靠性问题,增加了维护困难和工作量,严重时只有束之高阁,无法投入实际使用。
一. 软件可靠性与硬件可靠性的区别
软件可靠性与硬件可靠性之间主要存在以下区别:
1.最明显的是硬件有老化损耗现象,硬件失效是物理故障,是器件物理变化的必然结果,有浴盆曲线现象;软件不发生变化,没有磨损现象,有陈旧落后的问题,没有浴盆曲线现象。
2.硬件可靠性的决定因素是时间,受设计、生产、运用的所有过程影响,软件可靠性的决定因素是与输入数据有关的软件差错,是输入数据和程序内部状态的函数,更多地决定于人。
3.硬件的纠错维护可通过修复或更换失效的系统重新恢复功能,软件只有通过重设计。
4.对硬件可采用预防性维护技术预防故障,采用断开失效部件的办法诊断故障,而软件则不能采用这些技术。
5.事先估计可靠性测试和可靠性的逐步增长等技术对软件和硬件有不同的意义。
6.为提高硬件可靠性可采用冗余技术,而同一软件的冗余不能提高可靠性。
7.硬件可靠性检验方法已建立,并已标准化且有一整套完整的理论,而软件可靠性验证方法仍未建立,更没有完整的理论体系。
8.硬件可靠性已有成熟的产品市场,而软件产品市场还很新。
9.软件错误是永恒的,可重现的,而一些瞬间的硬件错误可能会被误认为是软件错误。
总的说来,软件可靠性比硬件可靠性更难保证,即使是美国宇航局的软件系统,其可靠性仍比硬件可靠性低一个数量级。
二. 影响软件可靠性的因素
软件可靠性是关于软件能够够满足需求功能的性质,软件不能满足需求是因为软件中的差错引起了软件故障。软件中有哪些可能的差错呢?
软件差错是软件开发各阶段潜入的人为错误:
1.需求分析定义错误。如用户提出的需求不完整,用户需求的变更未及时消化,软件开发者和用户对需求的理解不同等等。
2.设计错误。如处理的结构和算法错误,缺乏对特殊情况和错误处理的考虑等。
3.编码错误。如语法错误,变量初始化错误等。
4.测试错误。如数据准备错误,测试用例错误等。
5.文档错误。如文档不齐全,文档相关内容不一致,文档版本不一致,缺乏完整性等。
从上游到下游,错误的影响是发散的,所以要尽量把错误消除在开发前期阶段。
错误引入软件的方式可归纳为两种特性:程序代码特性,开发过程特性。
程序代码一个最直观的特性是长度,另外还有算法和语句结构等,程序代码越长,结构越复杂,其可靠性越难保证。
开发过程特性包括采用的工程技术和使用的工具,也包括开发者个人的业务经历水平等。
除了软件可靠性外,影响可靠性的另一个重要因素是健壮性,对非法输入的容错能力。
所以提高可靠性从原理上看就是要减少错误和提高健壮性。
三. 提高软件可靠性的方法和技术

1.建立以可靠性为核心的质量标准
在软件项目规划和需求分析阶段就要建立以可靠性为核心的质量标准。这个质量标准包括实现的功能、可靠性、可维护性、可移植性、安全性、吞吐率等等,虽然还没有一个衡量软件质量的完整体系,但还是可以通过一定的指标来指定标准基线。
软件质量从构成因素上可分为产品质量和过程质量。
产品质量是软件成品的质量,包括各类文档、编码的可读性、可靠性、正确性,用户需求的满足程度等。
过程质量是开发过程环境的质量,与所采用的技术、开发人员的素质、开发的组织交流、开发设备的利用率等因素有关。
还可把质量分为动态质量和静态质量。静态质量是通过审查各开发过程的成果来确认的质量,包括模块化程度、简易程度、完整程度等内容。动态质量是考察运行状况来确认的质量,包括平均故障间隔时间(MTBF)、软件故障修复时间(MTRF)、可用资源的利用率。在许多实际工程中,人们一般比较重视动态质量而忽视静态质量。
所定的质量标准度量,至少应达到以下两个目的:
(1).明确划分各开发过程(需求分析过程,设计过程,测试过程,验收过程),通过质量检验的反馈作用确保差错及早排除并保证一定的质量。
(2).在各开发过程中实施进度管理,产生阶段质量评价报告,对不合要求的产品及早采取对策。
确定划分的各开发过程的质量度量:
(1).需求分析质量度量
需求分析定义是否完整、准确(有无二义性),开发者和用户间有没有理解不同的情况,文档完成情况等,要有明确的可靠性需求目标、分析设计及可靠性管理措施等。
(2).设计结果质量度量
设计工时,程序容量和可读性、可理解性,测试情况数,评价结果,文档完成情况等。
(3).测试结果质量度量
测试工时,差错状况,差错数量,差错检出率及残存差错数,差错影响评价,文档等,以及有关非法输入的处理度量。
(4).验收结果质量度量
完成的功能数量,各项性能指标,可靠性等。
最后选择一种可靠度增长曲线预测模型,如时间测量、个体测量、可用性,在后期开发过程中,用来计算可靠度增长曲线的差错收敛度。
在建立质量标准之后,设计质量报告及评价表,在整个开发过程中就要严格实施并及时作出质量评价,填写报告表。
2. 选择开发方法
软件开发方法对软件的可靠性也有重要影响。
目前的软件开发方法主要有Parnas方法、Yourdon方法、面向数据结构的Jackson方法和Warnier方法、PSL/PSA方法、原型化方法、面向对象方法、可视化方法、ICASE方法、瑞理开发方法等,其他还有BSP方法、CSF方法等。这里特别要提一下的是Parnas方法。
Parnas方法是最早的软件开发方法,是Parnas 在1972年提出来的,基本思想是在概要设计时预先估计未来可能发生变化,提出了信息隐藏的原则以提高软件的可靠性和可维护性。
在设计中要求先列出将来可能要变化的因素,在划分模块时将一些可能发生变化的因素隐含在某个模块的内部,使其他模块与此无关,这样就提高了软件的可维护性,避免了错误的蔓延,也就提高了软件的可靠性。还提出了提高可靠性的措施:
(1)考虑到硬件有可能出故障,接近硬件的模块要对硬件行为进行检查,及时发现错误。
(2)考虑到操作人员有可能失误,输入模块对输入数据进行合法性检查,是否合法、越权,及时纠错。
(3)考虑到软件本身有可能失误,加强模块间检查,防止错误蔓延。
对瑞理方法可能许多人还不熟悉,这里简要介绍一下。
瑞理(Rational)模式是美国瑞理软件工程公司发展出来的,其模式是:
面向对象;
螺旋式上升;
管理与控制;
高度自动化;
以管理观点和技术观点把软件生命周期划分为起始、规划、建构、转移、进化五个阶段,也可把这五个阶段归并为研究时期(起始和规划)和生产时期(建构和转移),最后是维护时期(进化),特别适合对高风险部分及变动需求的处理。
在以上的众多方法中,可视化方法主要用于与图形有关的应用,目前的可视化开发工具只能提供用户界面的可视化开发,对一些不需要复杂图形界面的应用不必使用这种方法;ICASE 技术还没有完全成熟,所以可视在方法和ICASE方法最多只能用作辅助方法。面向数据结构的方法、PSL/PSA方法及原型化方法只适合于中小型系统的开发。
面向对象的方法便于软件复杂性控制,有利于生产率的提高,符合人类的思维习惯,能自然地表达现实世界的实体和问题,具有一种自然的模型化能力,达到从问题空间到解空间的较为直接自然的映射。
在面向对象的方法中,由于大量使用具有高可靠性的库,其可靠性也就有了保证,用面向对象的方法也利于实现软件重用。
所以建议采用面向对象的方法,借鉴Parnas和瑞理模式的思想,在开发过程中再结合使用其他方法,吸取其它方法的优点。
3.软件重用
最大限度地重用现有的成熟软件,不仅能缩短开发周期,提高开发效率,也能提高软件的可维护性和可靠性。因为现有的成熟软件,已经过严格的运行检测,大量的错误已在开发、运行和维护过程中排除,应该是比较可靠的。在项目规划开始阶段就要把软件重用列入工作中不可缺少的一部分,作为提高可靠性的一种必要手段。
软件重用不仅仅是指软件本身,也可以是软件的开发思想方法、文档,甚至环境、数据等,包括三个方面内容的重用:
(1)开发过程重用,指开发规范、各种开发方法、工具和标准等。
(2)软件构件重用,指文档、程序和数据等。
(3)知识重用,如相关领域专业知识的重用。
一般用的比较多的是软件构件重用。
软件重用的过程如下:候选,选择,资格,分类和存储,查找和检索。在选择可重用构件时,一定要有严格的选择标准,可重用的构件必须是经过严格测试的、甚至是经过可靠性和正确性证明的构件,应模块化(实现单一、的完整的功能)、结构清晰(可读、可理解、规模适当),且有高度可适应性。
4.使用开发管理工具
开发一个大的软件系统,离不开开发管理工具,作为一个项目管理员,仅仅靠人来管理是不够的,需要有开发管理工具来辅助解决开发过程中遇到的各种各样的问题,以提高开发效率和产品质量。
如Intersolv公司的PVCS软件开发管理工具,在美国市场占有率已超过70%,使用PVCS可以带来不少好处:规范开发过程,缩短开发周期,减少开发成本,降低项目投资风险;自动创造完整的文档,便于软件维护;管理软件多重版本;管理和追踪开发过程中危及软件质量和影响开发周期的缺陷和变化,便于软件重用,避免数据丢失,也便于开发人员的交流,对提高软件可靠性,保证质量有很大作用。
在我国,开发管理工具并没有得到有效地使用,许多软件公司还停留在人工管理阶段,所开发的软件质量不会很高。
人的管理比较困难,在保证开发人员素质的同时,要保持人员的稳定性,尽可能避免人员的经常流动。人员流动影响了软件的质量,工作连续性难保证,继承者不可能对情况了解很清楚等,也可能影响工作进程等。PVCS也提供了适当的人员管理方法。
5.加强测试
软件开发前期各阶段完成之后,为进一步提高可靠性,只有通过加强测试来实现了。为最大限度地除去软件中的差错,改进软件的可靠性,就要对软件进行完备测试。要对一个大的软件系统进行完备测试是不可能的,所以要确定一个最小测试数和最大测试数,前者是技术性的决策,后者管理性的决策,在实际过程中要确定一个测试数量的下界。总的来说,要在可能的情况下,进行尽可能完备的测试。
谁来做测试呢?一般说来,用户不大可能来进行模块测试,模块测试应该由最初编写代码的程序员来进行,要在他们之间交换程序进行模块测试,自己设计的程序自己测试一般都达不到好的效果。
测试前要确定测试标准、规范,测试过程中要建立完整的测试文档,把软件置于配置控制下,用形式化的步骤去改变它,保证任何错误及对错误的动作都能及时归档。
测试规范包括以下三类文档:
(1)测试设计规范:详细描述测试方法,规定该设计及其有关测试所包括的特性。还应规定完成测试所需的测试用例和测试规程,规定特性的通过/失败判定准则。
(2)测试用例规范:列出用于输入的具体值及预期输出结果。规定在使用具体测试用例时对测试规程的各种限制。
(3)测试规程规范:规定对于运行该系统和执行指定的测试用例来实现有关测试所要求的所有步骤。
测试的方法多种多样:
(1)走查(Walk-through),即手工执行,由不同的程序员(非该模块设计者)读代码,并进行评论。
(2)机器测试,对给定的输入不会产生不合逻辑的输出。
(3)程序证明或交替程序表示。
(4)模拟测试,模拟硬件、I/O设备等。
(5)设计审查,关于设计的所有各方面的小组讨论会,利用所获得的信息,找出缺陷及违反标准的地方等。
以上可以交替并行循环执行,在实际测试过程中要使用测试工具提高效率。
除正常的测试之外,还要对软件进行可靠性测试,确保软件中没有对可靠性影响较大的故障。制定测试计划方案,按实际使用的概率分布随机选择输入,准确记录运行时间和结果,并对结果进行评价。
没有错误的程序同永动机一样是不可能达到的。一般常用排错方法有试探法、追溯法、归纳法、演绎法。还要使用适当的排错工具,如UNIX提供的sdb和dbx编码排错工具,这些排错工具只有浏览功能,没有修改功能,是实际的找错工具。
6.容错设计
提高可靠性的技术一般可以分为两类,一类是避免故障,在开发过程中,尽可能不让差错和缺陷潜入软件,这类常用的技术有:
算法模型化,把可以保证正确实现需求规格的算法模型化。
模拟模型化,为了保证在确定的资源条件下的预测性能的发挥,使软件运行时间、内存使用量及控制执行模型化。
可靠性模型,使用可靠性模型,从差错发生频度出发,预测可靠性。
正确性证明,使用形式符号及数学归纳法等证明算法的正确性。
软件危险分析与故障树分析:从设计或编码的结构出发,追踪软件开发过程中潜入系统缺陷的原因。
分布接口需求规格说明:在设计的各阶段使用形式的接口需求规格说明,以便验证需求的分布接口实现可能性与完备性。
这些技术一般都需要比较深厚的数学理论知识和模型化技术。
另一类就是采用冗余思想的容错技术。
容错技术的基本思想是使软件内潜在的差错对可靠性的影响缩小控制到最低程度。
软件的容错从原理上可分为错误分析、破坏程度断定、错误恢复、错误处理四个阶段。
常用的软件容错技术有N-版本技术、恢复块技术、多备份技术等。
N-版本程序设计是依据相同规范要求独立设计N个功能相等的程序(即版本)。独立是指使用不同的算法,不同的设计语言,不同的测试技术,甚至不同的指令系统等。
恢复块技术是使用自动前向错误恢复的故障处理技术。
以上这些技术可参考有关文献,这里要说的是防错性程序设计,在程序中进行错误检查。被动的防错性技术是当到达检查点时,检查一个计算机程序的适当点的信息。主动的防错性技术是周期性地搜查整个程序或数据,或在空闲时间寻找不寻常的条件。采用防错性程序设计,是建立在程序员相信自己设计的软件中肯定有错误这一基础上的,有的程序员可能对此不大习惯,因为他可能太相信自己,相信自己的程序只有很少错误,甚至没有错误,作为一个项目管理员应该能说服他或者强制他采用这种技术,虽然在设计时要花费一定的时间,但这对提高可靠性很有用。

Continue reading 【转】试论软件的可靠性及其保证

软件容错技术

1)恢复块方法

故障的恢复策略一般有两种:前向恢复和后向恢复。所谓前向恢复是指使当前的计算继续下去,把系统恢复成连贯的正确状态,弥补当前状态的不连贯情况,这需有错误的详细说明。所谓后向恢复是指系统恢复到前一个正确状态,继续执行。这种方法显然不适合实时处理场合。

1975年B.Randell提出了一种动态屏蔽技术棗恢复块方法。恢复块方法采用后向恢复策略。它提供具有相同功能的主块和几个后备块,一个块就是一个执行完整的程序段,主块首先投入运行,结束后进行验收测试,如果没有通过验收测试,系统经现场恢复后由一后备块运行。这一过程可以重复到耗尽所有的后备块,或者某个程序故障行为超出了预料,从而导致不可恢复的后果。设计时应保证实现主块和后备块之间的独立性,避免相关错误的产生,使主块和后备块之间的共性错误降到最低限度。验收测试程序完成故障检测功能,它本身的故障对恢复块方法而言是共性,因此,必须保证它的正确性。

图3.2恢复块方法

(2)N-版本程序设计

1977年出现的N版本程序设计,是一种静态的故障屏蔽技术,采用前向恢复的策略,其设计思想是用N个具有相同功能的程序同时执行一项计算,结果通过多数表决来选择。其中N份程序必须由不同的人独立设计,使用不同的方法,不同的设计语言,不同的开发环境和工具来实现。目的是减少N版本软件在表决点上相关错误的概率。另外,由于各种不同版本并行执行,有时甚至在不同的计算机中执行,必须解决彼此之间的同步问题。

图3.3 N版本程序设计

(3)防卫式程序设计

防卫式程序设计是一种不采用任何一种传统的容错技术就能实现软件容错的方法,对于程序中存在的错误和不一致性,防卫式程序设计的基本思想是通过在程序中包含错误检查代码和错误恢复代码,使得一旦错误发生,程序能撤消错误状态,恢复到一个已知的正确状态中去。其实现策略包括错误检测,破坏估计和错误恢复三个方面。

(4) 动态冗余。动态冗余的主要方式是多重模块待机储备,当系统检测到某工作模块出现错误时,就用一个备用的模块来顶替它并重新运行。

Continue reading 软件容错技术

Node.js 了解

http://blog.feshine.net/technology/460.html

http://www.infoq.com/cn/articles/nodejs-frameworks

http://sd.csdn.net/a/20101123/282337.html

很火,是口头上火!

我也喜欢它,毕竟是javascript!

  • 服务器端的JavaScript
  • 基于Google的V8创建
  • 事件触发、非阻塞的I/O。 类似于EventMachine或Twisted。
  • CommonJS模块系统。
  • 有8000行C/C++代码, 2000行Javascript代码,14个贡献者。

第三点我很感兴趣,但是不知道怎么回事,因为没用过啊。

------------------------------------------------------------------------------------------

http://fafeng.blogbus.com/logs/120975751.html

    Node.js是构建在JavaScript引擎V8之上的JavaScript环境,它是一个异步事件驱动I/O模型,它能够非常好地安装在Linux, Macintosh和Solaris,通过虚拟机MinGWCygwin(编译和运行方法)它也能运行在其它Unix和Windows平台。

    Node.js的特性

    1. 单线程

    2. 异步

    3. 非阻塞IO

    4. 事件驱动(详见Understanding the node.js event loop

    5. Google V8

 

目前只是看看,最重要的问题是,nodejs太年轻了!

如果能成熟起来,做web应用那是太强了:

1:前后端语言相同!

2:用web的方式思考!

3:很好的性能!

 

其最大的特点我看就是它的性能优势了,而这个特点主要也是得益于非阻塞IO加上事件驱动,看看这篇文章

对集中网络IO操作机制的比较:  http://blog.ureshika.com/archives/596.html

 

参考:

http://sd.csdn.net/a/20111102/306771.html 关于node.js语言的讨论

Continue reading Node.js 了解

http大文件上传

大文件上传要注意以下几点:

  • input type=file需要放在form中。
  • form的enctype="multipart/form-data"  ie5下encoding="multipart/form-data"
  • form的method=”post”
  • input type=file需要有name属性
  • form的target指向提交页面,如果是空则会提交本页造成页面刷新,可以使用指向隐藏的iframe来解决。
  • form中的其他非file类型字段是可以得到的,但是url中的参数不可得。
  • 参数顺序与html中input排列顺序相同。

以上通过org.apache.commons.fileupload包验证过,其他形式应该也是支持的。

  • input type=file的值是可以得到的是经过安全处理的值。
  • 基于安全原因,不能使用脚本设置input type=file的值。

参见:http://w3help.org/zh-cn/causes/HF1010

  • 如要实现cancel功能,将提交的iframe的src属性设置为’’即可,这导致提交abort。

Continue reading http大文件上传

【转】软件体系结构:定义及风格

我发现书上完全是照这个文章抄的。原文见 http://www.docin.com/p-23802653.html

软件体系结构:定义及风格

Software Architecture:

Definition, Common Software Architectural Style and more.

撰文 / 曾毅

软件体系结构的引入The beginning of Software Architecture

软件设计自从计算机诞生之日起,就存在着显式或是隐式的危机。而1968年,在Garmish召开的国际软件工程会议上人们迫切地感到了软件危机给计算机软件产业的发展带来的巨大阻力。软件危机的两个最大的问题便是:随着计算机软件技术的日新月异,软件的规模越来越大,软件复杂度越来越高。伴随着这两个问题的日益突出,整个软件系统结构的设计与规格说明便显得比在早期软件开发中占有重要地位的算法选择和计算问题的数据结构更为重要。代码级别的软件复用已经远远不能满足大型软件开发的需求。由此便引入了软件体系结构这一概念。

软件体系结构的定义Definition of Software Architecture

从抽象角度来说,软件体系结构包含对于用于构建系统的元素,元素之间的互操作,指导系统构成的模式以及模式上的约束的描述。大体上说来,一个特定系统风格就是由组件集以及各个组件集之间的交互定义的。这些软件系统风格便可以用在大型系统设计中。

虽然人们在很多年前就认识到了软件体系结构的设计使整个软件开发中的关键元素,但是对于软件体系结构的定义直至今日也没有达成一个共识。以下是在软件体系结构理论发展的若干年中比较有影响力的定义:

Dewayne Perry和A1ex Wolf的定义:软件体系结构是具有一定形式的结构化元素,即组件的集合,包括处理组件、数据组件和连接组件。处理组件负责对数据进行加工,数据组件是被加工的信息,连接组件把体系结构的不同部分组组合连接起来。

这一定义注重区分处理组件、数据组件和连接组件,这一方法在其他的定义和方法中基本上得到保持。

Mary Shaw和David Garlan在Software Architecture: Perspectives on an Emerging Discipline一书中指出:软件体系结构是软件设计过程中的一个层次,这一层次超越计算过程中的算法设计和数据结构设计。体系结构问题包括总体组织和全局控制、通讯协议、同步、数据存取,给设计元素分配特定功能,设计元素的组织,规模和性能,在各设计方案间进行选择等。软件体系结构处理算法与数据结构之上关于整体系统结构设计和描述方面的一些问题,如全局组织和全局控制结构、关于通讯、同步与数据存取的协议,设计组件功能定义,物理分布与合成,设计方案的选择、评估与实现等。

Bass,Ctements和Kazman在Software Architecture in Practice一书中给出如下的定义:一个程序或计算机系统的软件体系结构包括一个或一组软件组件、软件组件的外部的可见特性及其相互关系。其中,“软件外部的可见特性”是指软件组件提供的服务、性能、特性、错误处理、共享资源使用等。

通过对若干定义的学习和研究,我将为软件体系结构下一个这样的定义:软件体系结构为软件系统提供了结构、行为和属性的高级抽象,由构成系统的元素描述、这些元素的相互作用、指导元素集成的模式以及这些模式的约束组成。软件体系结构不仅指定了系统的组织结构和拓扑结构,并且显示了系统需求和构成系统的元素之间的对应关系,提供了一些设计决策的基本原理,是构建于软件系统之上的系统级复用。

软件体系结构的影响Definition of Software Architecture

软件体系结构贯穿于软件研发的整个生命周期内,具有重要的影响。这主要从以下三个方面来进行考察:

(1) 利益相关人员之间的交流:软件体系结构是一种常见的对系统的抽象,代码级别的系统抽象仅仅可以成为程序员的交流工具,而包括程序员在内的绝大多数系统的利益相关人员都借助软件体系结构来进行彼此理解、协商、达成共识或者相互沟通的基础。

(2) 系统设计的前期决策:软件体系结构是我们所开发的软件系统最早期设计决策的体现,而这些早期决策对软件系统的后续开发、部署和维护具有相当重要的影响。这也是能够对所开发系统进行分析的最早时间点。

(3) 可传递的系统级抽象:软件体系结构是关于系统构造以及系统各个元素工作机制的相对较小、却又能够突出反映问题的模型。由于软件系统具有的一些共通特性,这种模型可以在多个系统之间传递,特别是可以应用到具有相似质量属性和功能需求的系统中,并能够促进大规模软件的系统级复用。

常用软件体系结构

Common Software Architectural Style

一个小型的软件可能具有一种软件体系结构,而大型的软件一般由多种软件体系结构组成,软件体系结构没有定性的说只有几种风格,但是经过长期的大型软件设计与分析,人们总结出了一些最为常用的软件体系结构风格,总共有五种,分别是:

数据流风格Data Flow Style

数据流风格的体系结构中,我们可以在系统中找到非常明显的数据流,处理过程通常在数据流的路线上“自顶向下、逐步求精”,并且,处理过程依赖于执行过程,而不是数据到来的顺序。比较有代表性的是批作业序列风格、管道/过滤器风格。

图1:管道/过滤器风格的软件体系结构

在管道/过滤器风格的软件体系结构中,每个组件都有一组输入和输出,组件读输入的数据流,经过内部处理,然后产生输出数据流。这个过程通常通过对输入流的变换及增量计算来完成,所以在输入被完全消费之前,输出便产生了。因此,这里的组件被称为过滤器,这种风格的连接器就象是数据流传输的管道,将一个过滤器的输出传到另一过滤器的输入。此风格特别重要的过滤器必须是独立的实体,它不能与其它的过滤器共享数据,而且一个过滤器不知道它上游和下游的标识。一个管道/过滤器网络输出的正确性并不依赖于过滤器进行增量计算过程的顺序。编译器系统就具备典型的管道系统风格的体系结构。在该系统中,一个阶段(包括词法分析、语法分析、语义分析和代码生成)的输出是另一个阶段的输入。

管道/过滤器风格的软件体系结构具有许多很好的特点:

(1) 使得软组件具有良好的隐蔽性和高内聚、低耦合的特点;

(2) 允许设计者将整个系统的输入/输出行为看成是多个过滤器的行为的简单合成;

(3) 支持软件复用。

(4) 系统维护和增强系统性能简单。新的过滤器可以添加到现有系统中来;旧的可以被改进的过滤器替换掉;

(5) 允许对一些如吞吐量、死锁等属性的分析;

(6) 支持并行执行。每个过滤器是作为一个单独的任务完成,因此可与其它任务并行执行。这比下面将要阐述的一种“主-子程序风格”的单线程操作要灵活得多。

这种系统结构的弱点是:

(1) 通常导致进程成为批处理的结构。这是因为虽然过滤器可增量式地处理数据,但它们是独立的,所以设计者必须将每个过滤器看成一个完整的从输入到输出的转换。

(2) 不适合处理交互的应用。当需要增量地显示改变时,这个问题尤为严重。

(3) 因为在数据传输上没有通用的标准,每个过滤器都增加了解析和合成数据的工作,这样就导致了系统性能下降,并增加了编写过滤器的复杂性。

调用/返回风格的体系结构【Call-and-Return Style

调用/返回风格的体系结构在过去的30年之间占有重要的地位,是大型软件开发中的主流风格的体系结构。这类系统中呈现出比较明显的调用/返回的关系。调用/返回风格在常用软件体系结构风格中内涵是比较丰富的,分为:主-子程序风格,面向对象概念中的对象体系结构风格,以及层次型系统风格三种子风格。

Snap1

图 2:主-子程序风格的体系结构

-子程序风格的体系结构是一种经典的编程范型,主要应用在结构化程序设计当中。这种风格的主要目的是将程序划分为若干个小片段,从而使程序的可更改性大大提高。主-子程序体系结构风格有一定的层次性,主程序位于一层,下面可以再划分一级子程序,二级子程序甚至更多。需要特别注意的是主-子程序体系结构风格是单线程控制的。同一时刻只有一个孩子结点的子程序可以得到父亲结点的控制。总结一下主-子程序体系结构风格的特点:

(1)由于单线程控制,计算的顺序得以保障。

(2)并且有用的计算结果在同一时刻只会产生一个。

(3)单线程的控制可以直接由程序设计语言来支持

(4)分层推理机制:子程序的正确性与它调用的子程序的正确性有关。

对象风格的体系结构:抽象数据类型概念对软件系统有着重要作用,目前软件界已普遍转向使用面向对象系统。这种风格建立在数据抽象和面向对象的基础上,数据的表示方法和它们的相应操作封装在一个抽象数据类型或对象中。这种风格的组件是对象,或者说是抽象数据类型的实例。对象是一种被称作管理者(Manager)的组件,因为它负责保持资源的完整性(例如实现对属性,方法的封装)。对象是通过函数和过程调用来交互的。

 

 

图3:数据抽象和面向对象风格的体系结构

对象风格的体系结构具有以下的特点:

(1)对象抽象使得组件和组件之间的操作以黑箱的方式进行。

(2)封装性使得细节内容对外部环境得以良好的隐藏。对象之间的访问是通过方法调用来实现的。

(3)考虑操作和属性的关联性,封装完成了相关功能和属性的包装,并由对象来对它们进行管理。

(4)使用某个对象提供的服务并不需要知道服务内部是如何实现的。

数据抽象和面向对象风格的体系结构在现代的软件开发中广泛应用。但是,面向对象体系结构也存在着某些问题:

(1)对象之间的耦合度比较紧:为了使一个对象和另一个对象通过过程调用等进行交互,必须知道对象的标识。只要一个对象的标识改变了,就必须修改所有其他明确调用它的对象。

(2)必须修改所有显式调用它的其它对象,并消除由此带来的一些副作用。例如A使用了对象B,C也使用了对象B,那么,C对B的使用所造成的对A的影响可能是不可预测的。

分层风格的体系结构是将系统组织成一个层次结构,每一层为上层提供服务,并作为下层的客户端。在分层风格的体系结构中,一般内部的层只对相邻的层可见。层之间的连接器(conector)通过决定层间如何交互的协议来定义。

图4:分层风格的体系结构

这种风格支持基于可增加抽象层的设计。这样,允许将一个复杂问题分解成一个增量步骤序列的实现。由于每一层最多只影响两层,同时只要给相邻层提供相同的接口,允许每层用不同的方法实现,同样为软件复用提供了强大的支持。

分层风格的体系结构有许多可取的属性:

(1)支持基于抽象程度递增的系统设计:使设计者可以把一个复杂系统按递增的步骤进行分解;

(2)支持功能增强:因为每一层至多和相邻的上下层交互,因此功能的改变最多影响相邻的上下层;

(3)支持复用:只要提供的服务接口定义不变,同一层的不同实现可以交换使用。这样,就可以定义一组标准的接口,而允许各种不同的实现方法。

但是,分层风格的体系结构也有其不足之处:

(1)并不是每个系统都可以很容易地划分为分层风格的体系结构,甚至即使一个系统的逻辑结构是层次化的,出于对系统性能的考虑,系统设计师不得不把一些低级或高级的功能综合起来;

(2)很难找到一个合适的、正确的层次抽象方法。

总结一下调用/返回风格的软件体系结构:这类架构中的组件就是各种不同的操作单元(例如,子程序、对象、层次),而连接器则是这些对象之间的调用关系(例如,主-子程序调用,或者对象的方法以及层次体系结构中的协议)。调用-返回结构的优点在于,容易将大的架构分解为一种层次模型,在较高的层次,隐藏那些比较具体的细节,而在较低的层次,又能够表现出实现细节。在这类体系结构中,调用者和被调用者之间的关系往往比较紧密。在这样的情况下,架构的扩充通常需要被调用者和所有调用者都进行适当的修改。

虚拟机风格的体系结构【Virtual Machine Style

虚拟机风格的体系结构设计的初衷主要是考虑体系结构的可移植性。这种体系结构力图模拟它运行于其上的软件或者硬件的功能。

图5:虚拟机风格的体系结构

这种体系结构在很多场合都有用途:

n 它可以被用于模拟或者测试尚未构建成的软硬件系统,它还可以模拟灾难,(例如飞行模拟器,安全攸关的系统 ,这些在现实生活中测试太过于危险并且牺牲太大。

n 虚拟机的例子有:解释器,基于规则的系统,通用语言处理程序。

我们用解释器作一个例子,通过虚拟机特定模块的解释步骤如下所示:

n 解释引擎从被解释的模块中选择一条指令;

n 基于这条指令,引擎更新虚拟机内部的状态;

n 上述过程反复执行;

由于对程序的中断,查询和在运行时的修改能力,通过虚拟机来执行模块大大提高了其稳定性,但是由于在执行过程中附加了额外的计算量,性能方面必然会受到影响。

在虚拟机结构中,组件是被模拟的机器和实际的机器,而连接器则是一组转换规则,这组转换规则能够在保持被模拟的机器中的虚拟状态和逻辑不变的前提下,将操作转换为实际的机器中能够被理解的操作。

这类架构的突出特点是:

n 在虚拟机器环境中运行的代码不必须了解虚拟机的具体细节。

n 一旦运行环境发生变化,只需要重写虚拟机本身,而不是整个系统。

n 通常虚拟机会限制在其中运行的软件的行为,特别是那些以实现跨平台为目的的虚拟机,如Java虚拟机和.NET CLR。这类虚拟机往往希望虚拟机器的代码完全不了解虚拟机以外的现实世界。这是在灵活性、效率与软件跨平台性之间进行的一种折衷。

n 能够使系统的结构更具层次性,使用虚拟机提供的设施编写的代码,可以不考虑虚 拟机以外的实际环境,而在正确地实现了这种虚拟机的环境中执行。

虚拟机架构的缺点是灵活性略显不足,无法最大限度地发挥操作系统和硬件的性能,在虚拟机中运行的应用程序并不了解实际的硬件和操作系统的特性。

独立组件风格的体系结构【Independent Components Style

独立组件风格的体系结构由很多独立的通过消息交互的过程或者对象组成。

图6:独立组件风格的体系结构

这种软件体系结构通过对各自部分计算的解耦操作来达到易更改的目的。它们之间相互的传输数据,但是不直接控制双方。消息可能传递给:

· 指定的参与项 (交互过程风格);

· 未指定的参与项 使用发布/登陆范型(事件风格) 。

事件系统风格 是独立组件风格的一个子风格。其中的每一个独立组件在它们的相关环境中声明它们希望共享的数据,这个环境便是未指定的参与项。事件系统会充分利用消息管理器(message manager)在消息传递到消息管理器的时候来管理组件之间的交互,和调用组件。组件会注册它们希望提供或者希望收到的信息的类型。

图7: 事件系统风格

随后它们会发送这个注册的类型给消息管理器,这个消息管理器可能是一个对象引用。

通信处理风格也是独立组件风格的一个子风格。这是一个多处理系统。

客户端-服务器风格是一个非常著名的风格。这种风格设计的目标是达到可测量性的需求。

图8:通信处理风格

服务器用于向一个或者多个客户端提供数据服务,这个环境经常与网络连接一起出现。客户端向服务器发出一个请求,服务器同步地或者异步地执行客户端的请求。如果工作是同步的,服务器将返回给客户端数据和客户端控制权,如果是异步的,服务器只返回给客户端数据,因为这个时候服务器有自己的控制线程。

独立组件架构的特点是:

n 系统由松耦合的一些独立运行的计算单元构成,这些单元之间通过消息传递信息。一般情况下,这些独立的计算单元能够自主地完成一些计算任务。

n 消息的发出者通常并不知道谁会接收并处理这些消息,更不了解这些消息是如何被处理的。

n 由于系统基于消息,因此有较好的并发性能,容错性和可伸缩性。

n 独立组件系统中通常不存在比较明显的主-从结构。通常只有一个比较弱的服务器,甚至没有服务器。

仓库风格的体系结构【Data Centered (Repositories) Style

在仓库风格中,有两种不同的组件:中央数据结构(用于说明当前状态),和独立组件(在中央数据存贮上执行),仓库与外组件间的相互作用在系统中会有大的变化。

图9:仓库风格的体系结构

控制原则的选取产生两个主要的子类。若输入流中某类时间触发进程执行的选择,则仓库是一个传统型数据库;系统中的组件通常包括数据存储区,以及与这些存储区进行交流的进程或处理单元,而连接器则是对于存储区的访问。这类系统中,数据处理进程往往并不直接发生联系,它们之间的联系主要是通过共享的数据存储区来完成的。这种现象非常类似于在独立组件架构中的情况。另一方面,若中央数据结构的当前状态触发进程执行的选择,则仓库是一黑板系统。

Blackboard

(Shared data)

KS2

KS3

KS4

KS5

KS6

KS7

KS8

KS1

Computation

Memory

Direct access

图10: 黑板系统体系结构

黑板系统的传统应用是信号处理领域,如语音和模式识别。另一应用是松耦合代理数据共享存取。

仔细观察图4所示,可以发现黑板系统主要由三部分组成:

(1)知识源:知识源中包含独立的、与应用程序相关的知识,知识源之间不直接进行通讯,它们之间的交互只通过黑板来完成。

(2)黑板数据结构:黑板数据是按照与应用程序相关的层次来组织的解决问题的数据,知识源通过不断地改变黑板数据来解决问题。

           (3)控制:控制完全由黑板的状态驱动,黑板状态的改变决定使用的特定知识。

仓库风格的体系结构的优点在于可扩充性比较强,模块间耦合比较松散,便于扩充。

常用软件体系结构风格综合运用实例

Case Study for Common Software Architectural Style

基于OpenGIS规范的Web要素服务软件具有复杂的软件体系结构。这是一套基于面向对象技术构建的地理信息系统综合应用平台。整个的软件环境配置和所开发的系统程序架构如下图所示:是一个层次分明的分层体系结构风格。最底层为数据存储层,存储介质是Oracle 9i数据库。上一层是空间数据库引擎,完成底层元数据的提取,传输和转换。再向上一层是Web服务包装层,完成了Web要素服务的三大功能。三个主要层次之间的连接器便是三层都遵守的数据传输协议。每一层次只与相邻的层次有关,与彼此隔离的层次没有直接关系。

Database(Oracle 9i)

Compress

Web Service Wrapper

GetCapabilities

DescribeFeatureType

GetFeature

SDE Proxy

ArcSDE Client

ArcSDE

Server

ArcSDE Server

Config Info

(XML)

WFS Config Pro

ArcSDE client

Meta Data

GCompress Module

LZSS Module

图11:WFS系统层次体系结构

在Web要素服务软件的功能设计和实现上,三大功能块的设计采用的是面向对象体系结构

Client

(sRequest)

Invoker

execute()

DescribeFeatureType

ExecuteService()

BaseOperation

GetCapabilities

ExecuteService()

GetFeature

ExecuteServiceFT()

图12: WFS系统面向对象体系结构

由于三大功能都有一些基本的操作,所以设计为由BaseOperation基类派生出三大功能类。三大类中封装了各自隐私的数据和操作。各个操作之间的交互通过成员函数进行调用。三大功能类以及基类便是属性和方法的管理者(Manager)。成员函数在整个系统中完成过程调用的工作。

对于整个系统的应用,是一个典型的客户端-服务器风格。WFS服务器提供Server服务,若干个客户端通过Internet向服务器请求数据,服务器并行处理客户端的请求并将处理数据返回给客户端。

结束语Conclusion】

软件体系结构风格为系统级别的软件复用提供了可能。然而,对于应用体系结构风格来说,由于视角的不同,系统设计师有很大的选择空间。要为系统选择或设计某一个体系结构风格,必须根据特定项目的具体特点,进行分析比较后再确定,体系结构风格的使用几乎完全是特化的。随着软件研发技术的不断进步,软件体系结构的五种模式也不能完全代表体系结构的基本构成了,从而诞生了:正交软件体系结构,三层C/S体系结构,C/S与B/S混合软件体系结构等。不同的结构有不同的处理能力的强项和弱点,一个系统的体系结构应该根据实际需要进行选择,以解决实际问题。

参考文献【Bibliography

[1]Len Bass, Paul Clements, Software Architecture in Practice(Second Edition)

[2]Mary Shaw, David Garlan, Software Architecture: Perspectives on an Emerging Discipline

[3] D.Helic & N.Scherbakov, Software Paradigms

参见:

http://www.cnblogs.com/winter-cn/archive/2008/06/01/1211757.html

Continue reading 【转】软件体系结构:定义及风格

享元模式

这个享元翻译的不是很好,让初接触的不明所以。倒不如它的英文flyweight更直观。

这才发现成天使用的Extjs里面的Ext.fly原来就是这种模式!

参见:

--------------------------------------

Ext.fly = El.fly;
/**
* Gets the globally shared flyweight Element, with the passed node as the active element. Do not store a reference to this element -
* the dom node can be overwritten by other code.
* @param {String/HTMLElement} el The dom node or id
* @param {String} named (optional) Allows for creation of named reusable flyweights to
*                                  prevent conflicts (e.g. internally Ext uses "_internal")
* @static
* @return {Element} The shared Element object (or null if no matching element was found)
*/
El.fly = function(el, named){
    named = named || '_global';
    el = Ext.getDom(el);
    if(!el){
        return null;
    }
    if(!El._flyweights[named]){
        El._flyweights[named] = new El.Flyweight();
    }
    El._flyweights[named].dom = el;
    return El._flyweights[named];
};

---------------------------------

El._flyweights = {};
var flyFn = function(){};
flyFn.prototype = El.prototype;
var _cls = new flyFn();

// dom is optional
El.Flyweight = function(dom){
    this.dom = dom;
};

El.Flyweight.prototype = _cls;
El.Flyweight.prototype.isFlyweight = true;

Continue reading 享元模式

设计模式

参见

http://zh.wikipedia.org/wiki/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F_%28%E8%AE%A1%E7%AE%97%E6%9C%BA%29

http://blog.csdn.net/name_110/article/category/911282

http://coolshell.cn/articles/3320.html

 

模式名称描述设计模式》中提及代码大全》中提及[1]
创建型模式
抽象工厂模式

为一个产品族提供了统一的创建接口。当需要这个产品族的某一系列的时候,可以从抽象工厂中选出相应的系列创建一个具体的工厂类。

http://blog.ureshika.com/archives/646.html

工厂方法模式

定义一个接口用于创建对象,但是让子类决定初始化哪个类。工厂方法把一个类的初始化下放到子类。

  • java.lang.Proxy#newProxyInstance()
  • java.lang.Object#toString()
生成器模式

将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

  • java.lang.StringBuilder#append()
  • java.lang.StringBuffer#append()
惰性初始模式

推迟对象的创建、数据的计算等需要耗费较多资源的操作,只有在第一次访问的时候才执行。

对象池模式通过回收利用对象避免获取和释放资源所需的昂贵成本。
原型模式

用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

  • java.lang.Object#clone()
  • java.lang.Cloneable
单例模式

确保一个类只有一个实例,并提供对该实例的全局访问。

java.lang.Runtime#getRuntime()

多例模式确保一个类只有命名的实例,并提供对这些实例的全局访问。
资源获取为初始化通过绑定到合适对象的生命周期来确保资源被适当地释放。
结构型模式
适配器模式

将某个类的接口转换成客户端期望的另一个接口表示。适配器模式可以消除由于接口不匹配所造成的类兼容性问题。

 Snap1

  • java.util.Arrays#asList()
  • javax.swing.JTable(TableModel)
  • java.io.InputStreamReader(InputStream)
  • java.io.OutputStreamWriter(OutputStream)
  • javax.xml.bind.annotation.adapters.XmlAdapter#marshal()
  • javax.xml.bind.annotation.adapters.XmlAdapter#unmarshal()
桥接模式

将一个抽象与实现解耦,以便两者可以独立的变化。 JDBC

组合模式

把多个对象组成树状结构来表示局部与整体,这样用户可以一样的对待单个对象和对象的组合。

UI组件

 Snap2

  • javax.swing.JComponent#add(Component)
  • java.awt.Container#add(Component)
  • java.util.Map#putAll(Map)
  • java.util.List#addAll(Collection)
  • java.util.Set#addAll(Collection)
修饰模式

向某个对象动态地添加更多的功能。修饰模式是除类继承外另一种扩展功能的方法。

 Snap3

  • java.io.BufferedInputStream(InputStream)
  • java.io.DataInputStream(InputStream)
  • java.io.BufferedOutputStream(OutputStream)
  • java.util.zip.ZipOutputStream(OutputStream)
  • java.util.Collections#checked[List|Map|Set|SortedSet|SortedMap]()
外观模式

为子系统中的一组接口提供一个一致的界面, 外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

  • java.lang.Class
  • javax.faces.webapp.FacesServlet

我看不出来这两个的facade模式。一个大颗粒的服务函数是否就可以说是门面模式?

享元

通过共享以便有效的支持大量小颗粒对象。

  • Ext.fly
代理

为其他对象提供一个代理以控制对这个对象的访问。

  • RMI
行为型模式
黑板广义的观察者在系统范围内交流信息,允许多位读者和写者。
责任链

为解除请求的发送者和接收者之间耦合,而使多个对象都有机会处理这个请求。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它。

javax.servlet.Filter#doFilter()

命令

将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可取消的操作。

  • java.lang.Runnable
  • javax.swing.Action
解释器

给定一个语言, 定义它的文法的一种表示,并定义一个解释器, 该解释器使用该表示来解释语言中的句子。

java.text.Format

迭代器

提供一种方法顺序访问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示。

  • java.util.Iterator
  • java.util.Enumeration
中介者

包装了一系列对象相互作用的方式,使得这些对象不必相互明显作用,从而使它们可以松散偶合。当某些对象之间的作用发生改变时,不会立即影响其他的一些对象之间的作用,保证这些作用可以彼此独立的变化。

  • java.util.concurrent.ExecutorService#<T> Future<T> submit(Callable<T> task)

让一个复杂的交互变得简单明了,买房者与售房者在中介介入下,是不能直接联系的,双方只会和中介联系。

备忘录

备忘录对象是一个用来存储另外一个对象内部状态的快照的对象。备忘录模式的用意是在不破坏封装的条件下,将一个对象的状态捉住,并外部化,存储起来,从而可以在将来合适的时候把这个对象还原到存储起来的状态。

  • java.io.Serializable
空对象

通过提供默认对象来避免空引用。

  • java.util.Collections#emptyList()
  • java.util.Collections#emptyMap()
  • java.util.Collections#emptySet()
观察者模式

在对象间定义一个一对多的联系性,由此当一个对象改变了状态,所有其他相关的对象会被通知并且自动刷新。

  • java.util.EventListener
规格以布尔形式表示的可重绑定的商业逻辑。
状态

让一个对象在其内部状态改变的时候,其行为也随之改变。状态模式需要对每一个系统可能取得的状态创立一个状态类的子类。当系统的状态变化时,系统便改变所选的子类。

  • java.util.Iterator
策略

定义一个算法的系列,将其各个分装,并且使他们有交互性。策略模式使得算法在用户使用的时候能独立的改变。

  • java.util.Comparator#compare()
模板方法

模板方法模式准备一个抽象类,将部分逻辑以具体方法及具体构造子类的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现。先构建一个顶级逻辑框架,而将逻辑的细节留给具体的子类去实现。

jsf中绘制一个组件:

  • renderBegin
  • renderChildren
  • renderEnd
访问者

封装一些施加于某种数据结构元素之上的操作。一旦这些操作需要修改,接受这个操作的数据结构可以保持不变。访问者模式适用于数据结构相对未定的系统,它把数据结构和作用于结构上的操作之间的耦合解脱开,使得操作集合可以相对自由的演化。

访问者对被访问者结构不熟悉,首先需要被访问者允许它来访问(accept),然后由被访问者领着访问者依次访问内部结构,针对每个结构做出不同操作。

并发型模式
主动对象
阻碍
双重检查锁定
守卫
领导者/追随者
监测对象模式
读写锁
调度
线程池模式
线程特定存储
反应器

Continue reading 设计模式

Pagination


Total views.

© 2013 - 2024. All rights reserved.

Powered by Hydejack v6.6.1