<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Program/Algorithm | Hessian's Blog</title><link>https://hessian.cn/cat/program/algorithm</link><description>Hessian 的技术笔记：Linux、C++、网络与嵌入式</description><language>zh-CN</language><atom:link href="https://hessian.cn/cat/program/algorithm/index.xml" rel="self" type="application/rss+xml"/><item><title>[转]LZW数据压缩算法的原理分析</title><link>https://hessian.cn/p/593.html</link><pubDate>Mon, 12 May 2008 13:30:00 +0800</pubDate><guid>https://hessian.cn/p/593.html</guid><description>src:http://www.cnblogs.com/jillzhang/archive/2006/11/06/551298.html&#10;   我希望通过本文的介绍，能给那些目前不太了解lzw算法和该算法在gif图像中应用，但渴望了解它的人一些启发和帮助。抛砖引玉而已，更希望园子里面兄弟提出宝贵的意见。&#10;1.LZW的全称是什么?&#10;   Lempel-Ziv-Welch (LZW).&#10;2. LZW的简介和压缩原理是什么？&#10;   LZW压缩算法是一种新颖的压缩方法，由Lemple-Ziv-Welch 三人共同创造，用他们的名字命名。它采用了一种先进的串表压缩，将每个第一次出现的串放在一个串表中，用一个数字来表示串，压缩文件只存贮数字，则不存贮 串，从而使图象文件的压缩效率得到较大的提高。奇妙的是，不管是在压缩还是在解压缩的过程中都能正确的建立这个串表，压缩或解压缩完成后，这个串表又被丢 弃。&#10;   LZW算法中，首先建立一个字符串表，把每一个第一次出现的字符串放入串表中，并用一个数字来表示，这个数字与此字符串在串表中的位置有关，并将这个数字 存入压缩文件中，如果这个字符串再次出现时，即可用表示它的数字来代替，并将这个数字存入文件中。压缩完成后将串表丢弃。如"print" 字符串，如果在压缩时用266表示，只要再次出现，均用266表示，并将"print"字符串存入串表中，在图象解码时遇到数字266，即可从串表中查出 266所代表的字符串"print"，在解压缩时，串表可以根据压缩数据重新生成。&#10;3.在详细介绍算法之前，先列出一些与该算法相关的概念和词汇&#10;   1)’Character’: 字符，一种基础数据元素，在普通文本文件中，它占用1个单独的byte，而在图像中，它却是 一种代表给定像素颜色的索引值。&#10;   2)’CharStream’：数据文件中的字符流。&#10;   3)’Prefix’:前缀。如这个单词的含义一样，代表着在一个字符最直接的前一个字符。一个前缀字符长度可以为0,一个prefix和一个character可以组成一个字符串(string),&#10;   4)’Suffix’: 后缀，是一个字符，一个字符串可以由(A,B)来组成，A是前缀,B是后缀,当A长度为0的时候，代表Root，根&#10;   5)’Code:码,用于代表一个字符串的位置编码&#10;   6)’Entry’，一个Code和它所代表的字符串(string)&#10;4.压缩算法的简单示例，不是完全实现LZW算法，只是从最直观的角度看lzw算法的思想&#10;    对原始数据ABCCAABCDDAACCDB进行LZW压缩&#10;    原始数据中，只包括4个字符(Character),A,B,C,D,四个字符可以用一个2bit的数表示，0-A,1-B,2-C,3-D,从最直观的角度看，原始字符串存在重复字符：ABCCAABCDDAACCDB，用4代表AB,5代表CC，上面的字符串可以替代表示为:45A4CDDAA5DB,这样是不是就比原数据短了一些呢！&#10;5.LZW算法的适用范围&#10;   为了区别代表串的值(Code)和原来的单个的数据值(String)，需要使它们的数值域不重合，上面用0-3来代表A-D,那么AB就必须用大于3的 数值来代替，再举另外一个例子，原来的数值范围可以用8bit来表示，那么就认为原始的数的范围是0～255，压缩程序生成的标号的范围就不能为 0～255（如果是0-255，就重复了）。只能从256开始，但是这样一来就超过了8位的表示范围了，所以必须要扩展数据的位数，至少扩展一位，但是这样不是增加了1个字符占用的空间了么？但是却可以用一个字符代表几个字符，比如原来255是8bit,但是现在用256来表示254，255两个数，还是划得来的。从这个原理可以看出LZW算法的适用范围是原始数据串最好是有大量的子串多次重复出现，重复的越多，压缩效果越好。反之则越差，可能真的不减反增了。&#10;6.LZW算法中特殊标记&#10;   随着新的串(string)不断被发现，标号也会不断地增长，如果原数据过大，生成的标号集（string table)会越来越大，这时候操作这个集合就会产生效率问题。如何避免这个问题呢?Gif在采用lzw算法的做法是当标号集足够大的时候，就不能增大 了，干脆从头开始再来，在这个位置要插入一个标号，就是清除标志CLEAR，表示从这里我重新开始构造字典，以前的所有标记作废，开始使用新的标记。&#10;这时候又有一个问题出现，足够大是多大？这个标号集的大小为比较合适呢？理论上是标号集大小越大，则压缩比率就越高，但开销也越高。 一般根据处理速度和内存空间连个因素来选定。GIF规范规定的是12位，超过12位的表达范围就推倒重来，并且GIF为了提高压缩率，采用的是变长的字 长。比如说原始数据是8位，那么一开始，先加上一位再说，开始的字长就成了9位，然后开始加标号，当标号加到512时，也就是超过9为所能表达的最大数据 时，也就意味着后面的标号要用10位字长才能表示了，那么从这里开始，后面的字长就是10位了。依此类推，到了2^12也就是4096时，在这里插一个清 除标志，从后面开始，从9位再来。&#10;GIF规定的清除标志CLEAR的数值是原始数据字长表示的最大值加1，如果原始数据字长是8，那么清除标志就是256，如果原始数据字长为4那么就是16。另外GIF还规定了一个结束标志END，它的值是清除标志CLEAR再加1。由于GIF规定的位数有1位（单色图），4位（16色）和8位（256色），而1位的情况下如果只扩展1位，只能表示4种状态，那么加上一个清除标志和结束标志就用完了，所以1位的情况下就必须扩充到3位。其它两种情况初始的字长就为5位和9位。此处参照了http://blog.csdn.net/whycadi/&#10;7.用lzw算法压缩原始数据的示例分析&#10;   输入流，也就是原始的数据为:255,24,54,255,24,255,255,24,5,123,45,255,24,5,24,54………………&#10;   这个正好可以看到是gif文件中像素数组的一部分，如何对它进行压缩&#10;   因为原始数据可以用8bit来表示，故清除标志Clear=255+1 =256,结束标志为End=256+1=257，目前标号集为&#10;   0 1 2 3 ………………………………………………………………………255 CLEAR END&#10;   第一步,读取第一个字符为255,在标记表里面查找，255已经存在，我们已经认识255了，不做处理&#10;   第二步,取第二个字符，此时前缀为A,形成当前的Entry为(255,24),在标记集合不存在，我们并不认识255,24好，这次你小子来了，我就记住你，把它在标记集合中标记为258,然后输出前缀A,保留后缀24，并作为下一次的前缀（后缀变前缀)&#10;第三步，取第三个字符为54，当前Entry(24,54),不认识，记录(24,54)为标号259,并输出24,后缀变前缀&#10;    第四部：取第四个字符255,Entry=(54,255),不认识，记录(54,255)为标号260,输出54,后缀变前缀&#10;   第五步   取第5个字符24，entry=(255,24),啊，认识你，这不是老258么，于是把字符串规约为258，并作为前缀&#10;   第六步 取第六个字符255,entry=(258,255)，不认识，记录(258,255)为261,输出258,后缀变前缀&#10;   …….&#10;一直处理到最后一个字符,&#10;用一个表记录处理过程&#10;   CLEAR=256,END=257&#10;第几步 前缀 后缀 Entry 认识(Y/N) 输出 标号 1 255 （，255） 2 255 24 (255,24)       N 255 258 3 24 54 (24,54)       N 24 259 4 54 255    (54,255)       N 54 260 5 255 24 (255,24)       Y 6 258 255 (258,255)       N 258 261 7 255 255 (255,255)       N 255 262 …..&#10;上面这个示例有些不能完整体现，另外一个例子是&#10;原输入数据为:A B A B A B A B B B A B A B A A C D A C D A D C A B A A A B A B …..&#10;采用LZW算法对其进行压缩，压缩过程用一个表来表述为:&#10;注意原数据中只包含4个character,A,B,C,D&#10;用两bit即可表述，根据lzw算法，首先扩展一位变为3为,Clear=2的2次方+1=4; End=4+1=5;&#10;初始标号集因该为&#10;0 1 2 3 4 5 A B C D Clear End 而压缩过程为:&#10;第几步 前缀 后缀 Entry 认识(Y/N) 输出 标号 1 A （，A） 2 A B (A,B)       N A 6 3 B A (B,A)       N B 7 4 A B    (A,B)       Y 5 6 A (6,A)       N 6 8 6 A B (A,B)       Y 7 6 A (6,A)      Y 8 8 B (8,B)        N 8 9 9 B B (B,B)        N B 10 10 B B (B,B)        Y 11 10 A (10,A)        N 10 11 12 A B (A,B)        Y …..&#10;当进行到第12步的时候，标号集应该为&#10;0 1 2 3 4 5 6 7 8 9 10 11 A B C D Clear End AB BA 6A 8B BB 10A 8.LZW算法的伪代码实现&#10;</description></item><item><title>[转]磨练构建正则表达式模式的技能</title><link>https://hessian.cn/p/408.html</link><pubDate>Mon, 12 Nov 2007 21:49:00 +0800</pubDate><guid>https://hessian.cn/p/408.html</guid><description>转自:http://www.ibm.com/developerworks/cn/aix/library/au-expressions.html&#10;</description></item><item><title>[转]澄清Java（接口与继承）</title><link>https://hessian.cn/p/321.html</link><pubDate>Sat, 10 Nov 2007 20:16:00 +0800</pubDate><guid>https://hessian.cn/p/321.html</guid><description>计算机学院研二的兄弟与我讨论Java，一见面，几个问题全是关于接口，接口有什么用？为什么要用接口？什么时候该使用接口？很庆幸他们不是问我 Java如何连接SQL Server，或者是如何开发J2EE应用，这类问题有杀伤力，避之则吉。今年计算机学院本科有个毕业设计课题是做J2ME，选这个题目的学生在5月末都还在苦着脸研究java.util.*这个包，这个这个……唉。&#10;</description></item><item><title>补码是什么？</title><link>https://hessian.cn/p/449.html</link><pubDate>Wed, 20 Jun 2007 09:18:00 +0800</pubDate><guid>https://hessian.cn/p/449.html</guid><description>用[ｘ]表示机器数（原码），ｘ是真值（二进制）&#10;   ｘ＝+0.1001,则[ｘ]原＝0.1001&#10;ｘ＝-0.1001,则[ｘ]原＝1.1001&#10;</description></item><item><title>计算机寄存器</title><link>https://hessian.cn/p/654.html</link><pubDate>Wed, 20 Jun 2007 09:11:00 +0800</pubDate><guid>https://hessian.cn/p/654.html</guid><description>寄存器是中央处理器内的其中组成部份。寄存器是有限存贮容量的高速存贮部件，它们可用来暂存指令、数据和位址。在中央处理器的控制部件中，包含的寄存器有指令寄存器(IR)和程序计数器(PC)。在中央处理器的算术及逻辑部件中，包含的寄存器有累加器(ACC)。&#10;寄存器（Register）&#10;</description></item><item><title>[转]Windows API</title><link>https://hessian.cn/p/521.html</link><pubDate>Wed, 20 Jun 2007 09:01:00 +0800</pubDate><guid>https://hessian.cn/p/521.html</guid><description>1.什么是Windows API? Windows 这个多作业系统除了协调应用程式的执行、分配内存、管理系统资源…之外， 她同时也是一个很大的服务中心，调用这个服务中心的各种服务(每一种服务就是一个函数)，可以帮应用程式达到开启视窗、描绘图形、使用周边设备…等目的， 由於这些函数服务的对象是应用程式(Application)， 所以便称之为 Application Programming Interface，简称 API 函数。WIN32 API也就是MicrosoftWindows 32位平台的应用程序编程接口。</description></item><item><title>在数据库中存储层次数据</title><link>https://hessian.cn/p/371.html</link><pubDate>Fri, 25 May 2007 15:03:00 +0800</pubDate><guid>https://hessian.cn/p/371.html</guid><description>作者：Gijs Van Tulder&#10;翻译：ShiningRay @ NirvanaStudio 无论你要构建自己的论坛，在你的网站上发布消息还是书写自己的cms [1]程序，你都会遇到要在数据库中存储层次数据的情况。同时，除非你使用一种像XML [2]的数据库，否则关系数据库中的表都不是层次结构的，他们只是一个平坦的列表。所以你必须找到一种把层次数据库转化的方法。&#10;存储树形结构是一个很常见的问题，他有好几种解决方案。主要有两种方法：邻接列表模型和改进前序遍历树算法&#10;</description></item><item><title>树形结构问题的一种解决办法</title><link>https://hessian.cn/p/415.html</link><pubDate>Fri, 25 May 2007 15:01:00 +0800</pubDate><guid>https://hessian.cn/p/415.html</guid><description>在一个标准的树形结构里面，一般要想知道的操作基本上有查询子树和查询所有父树（路径），还有就是查询子树自身的深度问题，通过前些日子的总结发现一种结构可以很好的满足这些要求。&#10;id parentID   name        path&#10;———————————-&#10;1     0              图书          0,1&#10;2     1             管理类       0,1,2&#10;3     2            名家作品     0,1,2,3&#10;4     2            国内          0,1,2,4&#10;5     2            外国          0,1,2,5&#10;6     0            文学类       0,6&#10;7     6            小说          0,6,7&#10;</description></item><item><title>再什么是构件</title><link>https://hessian.cn/p/532.html</link><pubDate>Fri, 11 May 2007 17:20:00 +0800</pubDate><guid>https://hessian.cn/p/532.html</guid><description>中科永联高级技术培训中心（www.itisedu.com）&#10;      构件是系统中实际存在的可更换部分，它实现特定的功能，符合一套接口标准并实现一组接口。构件代表系统中的一部分物理实施，包括软件代码（源代码、二进制代码或可执行代码）或其等价物（如脚本或命令文件）。在图中，构件表示为一个带有标签的矩形。&#10;部署构件的示例&#10;可执行文件 例如 .exe 文件 链接库 例如 .dll 文件 Applet 例如 Java 中的 .class 文件 Web 页面 例如 .htm 和 .html 文件 数据库表 工作产品构件的示例&#10;源代码文件 例如 C++ 和 CORBA IDL 中的 .h、.cpp 和 .hpp 文件，或 Java 中的 .java 文件 二进制文件 例如链接到可执行文件的 .o 文件和 .a 文件。 SOM 文件 IDL 和一些绑定 编译文件 例如 UNIX 中的 makefile 使用&#10;设计中的类和对象被作为部署构件进行实施。您需要确定如何将设计类映射为代码；这应该在项目专用的设计指南中有所说明。&#10;有关如何将设计类映射为代码的详细信息，请参见活动：实施构件。另请参见指南：类。&#10;      实施构件与修改构件在项目的配置管理环境中进行。实施员在为他们提供的专用开发工作区（请参见活动：创建开发工作区）中，按照工件：工作单所指定的内容开展工作。在该工作区中，创建源元素并将其置于配置管理之下，或者在通常的检出、编辑、构建、单元测试、检入周期中进行修改（请参见活动：进行变更）。完成某个构件集（根据一个或多个工作单的定义以及即将生成的工作版本要求）后，实施员将把有关新的和修改过的构件交付（请参见活动：交付变更内容）到子系统集成工作区，以便与其他实施员的工作进行集成。最后，实施员可以在方便的时候对专用开发工作区进行更新（或者重新调整基线），使该工作区与子系统集成工作区保持一致（请参见活动：更新工作区）。&#10;当实施类时，应遵循编程指南。&#10;实施的主要基础是具有公有操作、属性与关联关系的类。务必要注意，并不是所有公有操作、属性与关联关系都在设计过程中定义。&#10;实施的辅助基础是用例实现，用例实现显示了类和对象如何通过交互来执行用例。&#10;最好以递增的方式实施类；编译、链接和运行一些回归测试，每天进行三两次。&#10;在从零开始实施一个类之前，可考虑修改现有的实施类（一般可通过建立子类或进行实例化来修改）。&#10;实施操作 要实施操作，请执行以下步骤： 选择算法 选择适合算法的数据结构 根据需要定义新的类和操作 编写操作代码 选择算法&#10;许多操作都十分简单，可以从该操作及其规约中立即实施。&#10;之所以需要特殊算法，主要是为了实施定义了规约的复杂操作，并优化那些以简单但却低效的算法为定义的操作。&#10;选择适合算法的数据结构&#10;选择算法包括选择算法所基于的数据结构。许多实施数据结构是容器类，例如数组、列表、队列、栈、集合、无序单位组，以及这些类的各种不同形式。许多面向对象的语言和编程环境都提供了具有这些可复用构件的类库。&#10;根据需要定义新的类和操作&#10;比如，可以使用新类来保存中间结果，也可对类添加新的低级操作来分解复杂操作。通常，这些操作是类的私有操作，所以在类之外看不见这些操作。&#10;编写操作代码&#10;要编写操作的代码，可从接口语句开始，例如 C++ 中的成员函数声明、Ada 中的子程序规约或 Visual Basic 中的方法。请遵循编程指南。&#10;实施构件工作流程明细&#10;实施状态 对象的状态可通过引用其属性值来实施，而不必作特殊说明。这种对象的状态转移将隐含于变化的属性值中，而变化的行为通过条件语句来编程。 但对于复杂行为，该方法不能令人满意，因为它往往会导致复杂的结构；而当添加更多状态或当行为发生变化时，将很难更改这些结构。&#10;如果构件（或其组成部分）的行为随状态而定，则通常会有一个或多个状态图来说明组成该构件的模型元素的行为。这些状态图可用作实施过程中的重要输入。有关详细信息，请参见指南：状态图。 状态图中所示的状态机将表现对象的状态，并详尽说明状态转移及所需的行为。可以通过以下几种方法来实施状态机：&#10;对于简单的状态机，定义一项列举可能状态的属性，然后使用该属性在 Java 或 C++ 中的 switch 语句中选择进入消息的行为。但这种方法不太适用于复杂的状态机，它可能会导致运行时性能降低。如需此方法的示例，请参见 [DOUG98]，第 4 章 4.4.3 对于较复杂的状态机，可使用状态模式。有关状态模式的说明，请参见 [GAM94]。[DOUG98]，第 6 章 6.2.3 状态模式也说明了这种方法 表驱动法对于极复杂的状态机十分有效，其特点是易于变更。当使用这种方法时，各个状态在表中都有相应的条目，这些条目将输入映射到后继状态和相关的转移动作。如需此方法的示例，请参见 [DOUG98]，第 6 章 6.2.3 状态表模式。 要实施具有并行子状态的状态机，可以将状态管理委派给主动对象（每个对象都被委派一个并行子状态），因为并行子状态代表了独立的计算（但仍可能进行交互）。每个子状态均可通过上述方法之一来进行管理。&#10;通过委托关系复用实施 如果一个类或一个类的某些部分可通过复用现有类来实施，则应通过委托关系（而不要继承）来实现。&#10;委托表示一个类借助于其他类来得以实施。该类通过使用变量来引用其他类的对象。当调用某操作时，该操作将调用被引用对象（属于被复用的类）中的操作，以实际执行该操作。这样，它就将职责委派给了其他类。&#10;实施关联关系 单向关联关系将作为指针（包含对象引用的属性）来进行实施。如果多重性为一，则将单向关联关系当作简单指针来实施。如果多重性为多个，则将其当作指针集来实施。但如果“多”端是有序排列的，则可以使用列表，而不使用集合。&#10;双向关联关系将作为属性，使用单向关联关系的技术在两个方向上实施。&#10;限定关联关系将作为限定对象中的查询表（如一个 Smalltalk Dictionary 类）来实施。查询表中的选择器值是限定词，而目标值是另一个类的对象。&#10;如果必须按顺序访问限定词的值，就应将限定词组织成经过排序的数组或树。在这种情况下，访问时间将与 log N 成比例，其中 N 为限定词值的数目。&#10;如果限定词取自于一个紧凑的有限集，就可以将限定词的值映射到一个整数范围，并将关联关系当作数组来有效地进行实施。如果关联关系已基本上填满（而不是稀疏填充），此方法会更加有效；而对于完全填满的有限集，它可以算是理想的方法。&#10;许多面向对象的语言和编程环境都提供了具有可复用构件的类库，可用于实施不同种类的关联关系。&#10;实施属性 可以作为内置基本变量、可复用的构件类或定义一个新类来实现属性。定义新类通常是较为灵活的方法，但它却会带来不必要的间接性。例如，实施雇员的社会保障号时，既可将它作为类型“字符串”的属性，也可将它作为一个新类。&#10;属性的备选实施。&#10;另一种可能的情况是：属性组组成了新类，如下例所示。这两种实施都是正确的。&#10;将 Line 中的属性当作 Point 类的关联关系来实施。&#10;向设计提供反馈 在以上任何步骤中，如果发现了设计错误，都必须向设计提供返工反馈。如果所需的变更较小，就可以由同一个人来设计并实施类，而无需提出正式的变更请求。他可在设计中进行变更。&#10;如果所需的变更影响到几个类（例如在公有操作中的变更），则应向 CCB（变更控制委员会）提交正式的变更请求。请参见活动：修复缺陷。&#10;评估代码 在开始单元测试之前，可以先作一些检查。测试是一项花费较多的工作，因此最好先执行以下几项检查： 始终对代码进行编译。将编译器的警告等级设置到最详细的程度。 通过想像对操作进行检查。通读代码，尽可能考虑到所有情况，发现各种异常情况。一旦进行了新的实施活动，就需进行此项工作。 使用工具检查代码中是否存在错误。例如，使用静态代码规则检查程序。 © 1987 – 2001 Rational Software Corporation。版权所有。</description></item><item><title>又关于什么是框架</title><link>https://hessian.cn/p/400.html</link><pubDate>Fri, 11 May 2007 17:18:00 +0800</pubDate><guid>https://hessian.cn/p/400.html</guid><description>中科永联高级技术培训中心（www.itisedu.com）&#10;      框架（Framework）是整个或部分系统的可重用设计，表现为一组抽象构件及构件实例间交互的方法;另一种定义认为，框架是可被应用开发者定制的应用骨架。前者是从应用方面而后者是从目的方面给出的定义。       可以说，一个框架是一个可复用的设计构件，它规定了应用的体系结构，阐明了整个设计、协作构件之间的依赖关系、责任分配和控制流程，表现为一组抽象类以及其实例之间协作的方法，它为构件复用提供了上下文(Context)关系。因此构件库的大规模重用也需要框架。       构件领域框架方法在很大程度上借鉴了硬件技术发展的成就，它是构件技术、软件体系结构研究和应用软件开发三者发展结合的产物。在很多情况下，框架通常以构件库的形式出现，但构件库只是框架的一个重要部分。框架的关键还在于框架内对象间的交互模式和控制流模式。       框架比构件可定制性强。在某种程度上，将构件和框架看成两个不同但彼此协作的技术或许更好。框架为构件提供重用的环境，为构件处理错误、交换数据及激活操作提供了标准的方法。       应用框架的概念也很简单。它并不是包含构件应用程序的 小片程序，而是实现了某应用领域通用完备功能（除去特殊应用的部分）的底层服务。使用这种框架的编程人员可以在一个通用功能已经实现的基础上开始具体的系 统开发。框架提供了所有应用期望的默认行为的类集合。具体的应用通过重写子类(该子类属于框架的默认行为)或组装对象来支持应用专用的行为。       应用框架强调的是软件的设计重用性和系统的可扩充性,以缩短大型应用软件系统的开发周期，提高开发质量。与传统的基于类库的面向对象重用技术比较，应用框架更注重于面向专业领域的软件重用。应用框架具有领域相关性，构件根据框架进行复合而生成可运行的系统。框架的粒度越大，其中包含的领域知识就更加完整。       框架，即framework。其实就是某种应用的半成品，就是一组组件，供你选用完成你自己的系统。简单说就是使用别人搭好的舞台，你来做表演。而且，框架一般是成熟的，不断升级的软件。&#10;       框架的概念最早起源于Smalltalk环境，其中最著名的框架是Smalltalk 80的用户界面框架MVC(Model -View-Controller)。随着用户界面框架Interviews [Linton 89]和ET++ [Weinand 89] 的开发和发布，框架研究越来越受到研究人员的重视。虽然框架研究最初起源于用户界面领域，但它还被成功地应用到其他领域中，如操作系统 [Russo 90]、火警系统 [Molin 96a，Molin 96b] 等。Taligent公司于1992年成立后，框架研究受到了广泛的重视。该公司计划基于框架来开发一个完整的面向对象操作系统。另外，该公司还发布了一 套支持快速应用开发的工具集CommonPoint，其中包括了上百个面向对象框架 [Andert 94,Cotter 95]。&#10;框架目前还没有统一的定义，其中Ralph Johnson所给出的定义基本上为大多数研究人员所接受：       一个框架是一个可复用设计，它是由一组抽象类及其实例间协作关系来表达的 [Johnson 98]。&#10;      这个定义是从框架内涵的角度来定义框架的，当然也可以从框架用途的角度来给出框架的定义：&#10;      一个框架是在一个给定的问题领域内，一个应用程序的一部分设计与实现[Bosch 97]。&#10;      从以上两个定义可以看出，框架是对特定应用领域中的应用系统的部分设计和实现，它定义了一类应用系统(或子系统)的整体结构。框架将应用系统划分为类和对象，定义类和对象的责任，类和对象如何互相协作，以及对象之间的控制线程。这些共有的设计因素由框架预先定义，应用开发人员只须关注于特定的应用系统特有部分。框架刻画了其应用领域所共有的设计决策，所以说框架着重于设计复用，尽管框架中可能包含用某种程序设计语言实现的具体类。&#10;      一个基于框架开发的应用系统包含一个或多个框架，与框架相关的构件类，以及与应用系统相关的功能扩展。与应用系统相关的扩展包括与应用系统相关的类和对象。应用系统可能仅仅复用了面向对象框架的一部分，或者说，它可能需要对框架进行一些适应性修改，以满足系统需求。&#10;      面向对象的框架作为一种可复用的软件，在基于框架的软件开发过程中会涉及到框架的开发和利用两个方面的工作。框架的开发阶段在于产生领域中可复用的设计。 该阶段的主要结果是框架以及与框架相关的构件类。该阶段的一个重要活动是框架的演变和维护。象所有软件一样，框架也易于变化。产生变化的原因很多，如应用 出错，业务领域变化，等等。&#10;      不论是哪一种技术，最终都是为业务发展而服务的。从业务的角度来讲。首先，框架的是为了企业的业务发展和战略规划而服务的，他服从于企业的愿景 （vision）；其次，框架最重要的目标是提高企业的竞争能力，包括降低成本、提高质量、改善客户满意程度，控制进度等方面。最后，框架实现这一目标的 方式是进行有效的知识积累。软件开发是一种知识活动，因此知识的聚集和积累是至关重要的。框架能够采用一种结构化的方式对某个特定的业务领域进行描述，也 就是将这个领域相关的技术以代码、文档、模型等方式固化下来。&#10;一、框架要解决的问题&#10;      框架要解决的最重要的一个问题是技术整合的问题，在J2EE的 框架中，有着各种各样的技术，不同的软件企业需要从J2EE中选择不同的技术，这就使得软件企业最终的应用依赖于这些技术，技术自身的复杂性和技术的风险 性将会直接对应用造成冲击。而应用是软件企业的核心，是竞争力的关键所在，因此应该将应用自身的设计和具体的实现技术解耦。这样，软件企业的研发将集中在 应用的设计上，而不是具体的技术实现，技术实现是应用的底层支撑，它不应该直接对应用产生影响。&#10;      要理解这一点，我们来举一些例子：&#10;      一个做视频流应用的软件企业，他为电广行业提供整体的解决方案。他的优势在于将各种各样的视频硬件、服务器、和管理结合起来，因此他扮演的是一个集成商的 角色。因此他的核心价值在于使用软件技术将不同的硬件整合起来，并在硬件的整合层面上提供一个统一的管理平台。所以他的精力应该放在解决两个问题：&#10;      如何找到一种方法，将不同的硬件整合起来，注意，这里的整合并不是技术整合，而是一种思路上的整合。首先要考虑的绝对不是要使用什么技术，而是这些硬件需 要提供哪些服务，需要以什么样的方式进行管理。因此，这时候做的事情实际上是对领域进行建模。例如，我们定义任何一种硬件都需要提供两种能力，一种是统一 的管理接口，用于对所有硬件统一管理；另一种是服务接口，系统平台可以查询硬件所能够提供的服务，并调用这些服务。所以，设计的规范将会针对两种能力进 行。&#10;      另一个问题是如何描述这个管理系统的规范。你需要描述各种管理活动，以及管理中所涉及的不同实体。因为管理系统是针对硬件的管理，所以它是构架在硬件整合平台之上的。&#10;      在完成业务层面的设计之后，我们再来看看具体的技术实现。光有规范和设计是不够的，我们还需要选择一个优秀的技术。由于是对不同硬件的整合，我们想到采用Java提供的JMX技术。JMX技术适合用来进行系统整合，它定义了一个通用的规范，并给出了远程管理端口的一些默认实现。JMX已经经过了实践的检验，不少的应用服务器都采用了以JMX为基础的结构，例如有名的JBoss。JMX已经是一个很好的开始了，但是我们还需要在JMX的基础上再做一些工作。&#10;二、什么要用框架？&#10;      因为软件系统发展到今天已经很复杂了，特别是服务器端软件，设计到的知识，内容，问题太多。在某些方面使用别人成熟的框架，就相当于让别人帮你完成一些基 础工作，你只需要集中精力完成系统的业务逻辑设计。而且框架一般是成熟，稳健的，他可以处理系统很多细节问题，比如，事物处理，安全性，数据流控制等问 题。还有框架一般都经过很多人使用，所以结构很好，所以扩展性也很好，而且它是不断升级的，你可以直接享受别人升级代码带来的好处。&#10;      框架一般处在低层应用平台（如J2EE）和高层业务逻辑之间的中间层。&#10;      软件为什么要分层？&#10;      为了实现“高内聚、低耦合”。把问题划分开来各个解决，易于控制，易于延展，易于分配资源…总之好处很多啦：）。&#10;三、为什么要进行框架开发?       框架的最大好处就是重用。面向对象系统获得的最大的复用方式就是框架，一个大的应用系统往往可能由多层互相协作的框架组成。       由于框架能重用代码，因此从一已有构件库中建立应用变得非常容易，因为构件都采用框架统一定义的接口，从而使构件间的通信简单。       框架能重用设计。它提供可重用的抽象算法及高层设计，并能将大系统分解成更小的构件，而且能描述构件间的内部接口。这些标准接口使在已有的构件基础上通过 组装建立各种各样的系统成为可能。只要符合接口定义，新的构件就能插入框架中，构件设计者就能重用构架的设计。       框架还能重用分析。所有的人员若按照框架的思想来分析事务，那么就能将它划分为同样的构件，采用相似的解决方法，从而使采用同一框架的分析人员之间能进行沟通。       采用框架技术进行软件开发的主要特点包括： 领域内的软件结构一致性好； 建立更加开放的系统； 重用代码大大增加，软件生产效率和质量也得到了提高； 软件设计人员要专注于对领域的了解，使需求分析更充分； 存储了经验，可以让那些经验丰富的人员去设计框架和领域构件，而不必限于低层编程； 允许采用快速原型技术； 有利于在一个项目内多人协同工作；       大粒度的重用使得平均开发费用降低，开发速度加快，开发人员减少，维护费用降低，而参数化框架使得适应性、灵活性增强。 四、与框架相关的概念 1. 白盒与黑盒框架       框架可分为白盒(White-Box)与黑盒(Black-Box)两种框架。        基于继承的框架被称为白盒框架。所谓白盒即具备可视性，被继承的父类的内部实现细节对子类 而言都是可知的。利用白盒框架的应用开发者通过衍生子类或重写父类的成员方法来开发系统。子类的实现很大程度上依赖于父类的实现，这种依赖性限制了重用的 灵活性和完全性。但解决这种局限性的方法可以是只继承抽象父类，因为抽象类基本上不提供具体的实现。白盒框架是一个程序骨架，而用户衍生出的子类是这个骨 架上的附属品。       基于对象构件组装的框架就是黑盒框架。应用开发者通过整理、组装对象来获得系统的实现。用户只须了解构件的外部接口，无须了解内部的具体实现。另外，组装比继承更为灵活，它能动态地改变，继承只是一个静态编译时的概念。       在理想情况下，任何所需的功能都可通过组装已有的构件得到，事实上可获得的构件远远不能满足需求，有时通过继承获得新的构件比利用已有构件组装新构件更容 易，因此白盒和黑盒将同时应用于系统的开发中。不过白盒框架趋向于向黑盒框架发展，黑盒框架也是系统开发希望达到的理想目标。 2. 热点、食谱以及好莱坞原则        成功的框架开发需要确定领域专用的“热点” (Hot spot)。应用开发者在框架的基础上进行开发，只须扩展框架的某些部分，“热点”就是在应用领域的一种扩展槽，开发者根据自己的需要填充这些扩展槽。 “热点”使框架具有灵活性，如在具体的实现中，扩展槽可以被看成是一些抽象类，开发者通过重写抽象方法获得具体实现。       “食谱” (Cookbook)就是描述如何使用框架方法的文档。在“食谱”中包含了许多“烹饪”方法，这些“烹饪”方法相当于一些具体的操作步骤，描述了为解决某一专门问题如何使用框架的详细方法。框架的内部设计和实现细节通常不出现在“食谱”中。       框架的一个重要特征就是用户定义的方法经常被框架自身调用，而不是从用户的应用代码中调用。这种机制常称为“好莱坞原则”(Hollywood Principle)或“别调用我们，我们会调用您”。&#10;五、常见的JAVA框架有什么？&#10;WAF：&#10;全称：WEB APPLICATION FRAMEWORK&#10;主要应用方面：EJB层，（WEB层也有，但是比较弱）。&#10;主要应用技术：EJB等&#10;出处：java.sun.com/blueprints/code/index.html"&gt;http://java.sun.com/blueprints/code/index.html&#10;简述：这是SUN在展示J2EE平台时所用的例子PetStore(宠物商店系统)里面的框架。是SUN蓝皮书例子程序中提出的应用框架。它实现了 MVC和其他良好的设计模式。SUN的网站上有技术资料，最好下载PetStore来研究，WEBLOGIC里自带此系统，源码在beaweblogic700samplesserversrcpetstore。这是学习了解J2EE的首选框架。&#10;免费。&#10;Struts:&#10;主要应用方面：WEB层。&#10;主要应用技术：JSP,TagLib,JavaBean,XML等&#10;出处：http://jakarta.apache.org/struts/index.html&#10;简述：这是APACHE的开源项目，目前应用很广泛。基于MVC模式，结构很好，基于JSP。Jbuilder8里已经集成了STRUTS1.02的制作。&#10;免费。&#10;简述WAF+STRUTS结合的例子：WEB层用STRUTS，EJB层用WAF：&#10;JSP(TagLib)——&gt;ActionForm——&gt;Action ——&gt;&#10;Event——&gt;EJBAction——&gt;EJB    ——&gt;DAO——&gt;Database JSP（TagLib） (forward) &lt;——Action &lt;——EventResponse&lt;——                 Turbine：&#10;主要应用方面：WEB层。&#10;主要应用技术：servlet等&#10;出处：http://jakarta.apache.org/turbine/index.html&#10;简述：这是APACHE的开源项目。基于SERVLET。据说速度比较快，基于service（pluggable implementation可插拔的执行组件）的方式提供各种服务。&#10;免费。&#10;COCOON：&#10;主要应用方面：WEB层。&#10;主要应用技术：XML，XSP，servlet等&#10;出处：http://cocoon.apache.org/2.0/&#10;简述：这是APACHE的一个开源项目。基于XML，基于XSP（通俗地说，XSP是在XML静态文档中加入Java程序段后形成的动态XML文档。）。特点是可以与多种数据源交互，包括文件系统，数据库，LDAP，XML资源库，网络数据源等。&#10;免费。&#10;ECHO：&#10;主要应用方面：WEB层。&#10;主要应用技术：servlet等&#10;出处：http://www.nextapp.com/products/echo/&#10;简述：nextapp公司的一个开源项目。基于SERVLET。页面可以做的很漂亮，结合echopoint，可以作出很多图形效果（里面用了jfreechart包）。使用SWING的思想来作网页，把HTML当作JAVA的类来做。但是大量使用Session，页面分帧（Frame）很多,系统资源消耗很大。&#10;免费。&#10;JATO：&#10;全称：SUN ONE Application Framework&#10;主要应用方面：WEB层。&#10;主要应用技术：JSP,TagLib,JavaBean等&#10;出处：http://www.sun.com/&#10;简述：这是SUN推出的一个商业性框架，一看名字就知道是结合SUN ONE的平台推出的。我下载了JATO2.0看了一下，感觉有些简单，使用了JSP＋TagLib+JavaBean。如他的DOC所说JATO是适合用在小的WEB应用里。&#10;免费。&#10;TCF：&#10;全称：Thin-Client Framework&#10;主要应用方面：JAVA GUI。&#10;主要应用技术：JAVA application等&#10;出处：http://www.alphaworks.ibm.com/tech/tcf&#10;简 述：这是IBM出的一个框架。基于MVC模式，基于JAVA Application。推荐一篇介绍文章：java/j-tcf1/index.shtml"&gt;http://www- 900.ibm.com/developerWorks/cn/java/j-tcf1/index.shtml&#10;收费：每个企业对象license:2000美元。</description></item><item><title>关于什么是架构</title><link>https://hessian.cn/p/429.html</link><pubDate>Fri, 11 May 2007 17:03:00 +0800</pubDate><guid>https://hessian.cn/p/429.html</guid><description>中科永联高级技术培训中心（www.itisedu.com）&#10;    软件架构（software architecture）是一系列相关的抽象模式，用于指导大型软件系统各个方面的设计。 软件架构是一个系统的草图。软件架构描述的对象是直接构成系统的抽象组件。各个组件之间的连接则明确和相对细致地描述组件之间的通讯。在实现阶段，这些抽象组件被细化为实际的组件，比如具体某个类或者对象。在面向对象领域中，组件之间的连接通常用接口_(计算机科学)来实现。&#10;    软件体系结构是构建计算机软件实践的基础。与建筑师设定建筑项目的设计原则和目标，作为绘图员画图的基础一样，一个软件架构师或者系统架构师陈述软件构架以作为满足不同客户需求的实际系统设计方案的基础。&#10;      软件构架是一个容易理解的概念，多数工程师（尤其是经验不多的工程师）会从直觉上来认识它，但要给出精确的定义很困难。特别是，很难明确地区分设计和构架：构架属于设计的一方面，它集中于某些具体的特征。&#10;      在“软件构架简介”中，David Garlan 和 Mary Shaw 认为软件构架是有关如下问题的设计层次：“在计算的算法和数据结构之外，设计并确定系统整体结构成为了新的问题。结构问题包括总体组织结构和全局控制结 构；通信、同步和数据访问的协议；设计元素的功能分配；物理分布；设计元素的组成；定标与性能；备选设计的选择。”[GS93]&#10;       但构架不仅是结构；IEEE Working Group on Architecture 把其定义为“系统在其环境中的最高层概念”[IEEE98]。构架还包括“符合”系统完整性、经济约束条件、审美需求和样式。它并不仅注重对内部的考虑，而且还在系统的用户环境和开发环境中对系统进行整体考虑，即同时注重对外部的考虑。&#10;      在 Rational Unified Process 中，软件系统的构架（在某一给定点）是指系统重要构件的组织或结构，这些重要构件通过接口与不断减小的构件与接口所组成的构件进行交互。&#10;     从和目的、主题、材料和结构的联系上来说，软件架构可以和建筑物的架构相比拟。一个软件架构师需要有广泛 的软件理论知识和相应的经验来事实和管理软件产品的高级设计。软件架构师定义和设计软件的模块化，模块之间的交互，用户界面风格，对外接口方法，创新的设 计特性，以及高层事物的对象操作、逻辑和流程。&#10;是一般而言，软件系统的架构（Architecture）有两个要素：&#10;·它是一个软件系统从整体到部分的最高层次的划分。&#10;一个系统通常是由元件组成的，而这些元件如何形成、相互之间如何发生作用，则是关于这个系统本身结构的重要信息。&#10;详细地说，就是要包括架构元件（Architecture Component）、联结器（Connector）、任务流（Task-flow）。所谓架构元素，也就是组成系统的核心"砖瓦"，而联结器则描述这些元件之间通讯的路径、通讯的机制、通讯的预期结果，任务流则描述系统如何使用这些元件和联结器完成某一项需求。&#10;·建造一个系统所作出的最高层次的、以后难以更改的，商业的和技术的决定。&#10;在建造一个系统之前会有很多的重要决定需要事先作出，而一旦系统开始进行详细设计甚至建造，这些决定就很难更改甚至无法更改。显然，这样的决定必定是有关系统设计成败的最重要决定，必须经过非常慎重的研究和考察。&#10;      历史&#10;      早在1960年代，诸如E·W·戴克斯特拉就已经涉及软件架构这个概念了。自1990年代以来，部分由于在 Rational Software Corporation 和Microsoft内部的相关活动，软件架构这个概念开始越来越流行起来。&#10;      卡内基梅隆大学和加州大学埃尔文分校在这个领域作了很多研究。卡内基·梅隆大学的Mary Shaw和David Garlan于1996年写了一本叫做 Software Architecture perspective on an emerging discipline的书，提出了软件架构中的很多概念，例如软件组件、连接器、风格等等。 加州大学埃尔文分校的软件研究院所做的工作则主要集中于架构风格、架构描述语言以及动态架构。&#10;计算机软件的历史开始于五十年代，历史非常短暂，而相比之下建筑工程则从石器时代就开始了，人类在几千年的建筑设计实践中积累了大量的经验和教训。建筑设计基本上包含两点，一是建筑风格，二是建筑模式。独特的建筑风格和恰当选择的建筑模式，可以使一个独一无二。&#10;下面的照片显示了中美洲古代玛雅建筑，Chichen-Itza大金字塔，九个巨大的石级堆垒而上，九十一级台阶（象征着四季的天数）夺路而出，塔顶的神殿耸入云天。所有的数字都如日历般严谨，风格雄浑。难以想象这是石器时代的建筑物。&#10;图1、位于墨西哥Chichen-Itza（在玛雅语中chi意为嘴chen意为井）的古玛雅建筑。（摄影：作者） 软件与人类的关系是架构师必须面对的核心问题，也是自从软件进入历史舞台之后就出 现的问题。与此类似地，自从有了建筑以来，建筑与人类的关系就一直是建筑设计师必须面对的核心问题。英国首相丘吉尔说，我们构造建筑物，然后建筑物构造我 们（We shape our buildings, and afterwards our buildings shape us）。英国下议院的会议厅较狭窄，无法使所有的下议院议员面向同一个方向入座，而必须分成两侧入座。丘吉尔认为，议员们入座的时候自然会选择与自己政见 相同的人同时入座，而这就是英国政党制的起源。Party这个词的原意就是"方"、"面"。政党起源的关键就是建筑物对人的影响。&#10;在软件设计界曾经有很多人认为功能是最为重要的，形式必须服从功能。与此类似地，在建筑学界，现代主义建筑流派的开创人之一Louis Sullivan也认为形式应当服从于功能（Forms follows function）。&#10;几乎所有的软件设计理念都可以在浩如烟海的建筑学历史中找到更为遥远的历史回响。最为著名的，当然就是模式理论和XP理论。&#10;架构的目标是什么&#10;正如同软件本身有其要达到的目标一样，架构设计要达到的目标是什么呢？一般而言，软件架构设计要达到如下的目标：&#10;·可靠性（Reliable）。软件系统对于用户的商业经营和管理来说极为重要，因此软件系统必须非常可靠。&#10;·安全行（Secure）。软件系统所承担的交易的商业价值极高，系统的安全性非常重要。&#10;·可扩展性（Scalable）。软件必须能够在用户的使用率、用户的数目增加很快的情况下，保持合理的性能。只有这样，才能适应用户的市场扩展得可能性。 ·可定制化（Customizable）。同样的一套软件，可以根据客户群的不同和市场需求的变化进行调整。&#10;·可扩展性（Extensible）。在新技术出现的时候，一个软件系统应当允许导入新技术，从而对现有系统进行功能和性能的扩展&#10;·可维护性（Maintainable）。软件系统的维护包括两方面，一是排除现有的错误，二是将新的软件需求反映到现有系统中去。一个易于维护的系统可以有效地降低技术支持的花费&#10;·客户体验（Customer Experience）。软件系统必须易于使用。&#10;·市场时机（Time to Market）。软件用户要面临同业竞争，软件提供商也要面临同业竞争。以最快的速度争夺市场先机非常重要。&#10;架构的种类&#10;根据我们关注的角度不同，可以将架构分成三种：&#10;·逻辑架构、软件系统中元件之间的关系，比如用户界面，数据库，外部系统接口，商业逻辑元件，等等。&#10;比如下面就是笔者亲身经历过的一个软件系统的逻辑架构图&#10;图2、一个逻辑架构的例子&#10;从上面这张图中可以看出，此系统被划分成三个逻辑层次，即表象层次，商业层次和数据持久层次。每一个层次都含有多个逻辑元件。比如WEB服务器层次中有HTML服务元件、Session服务元件、安全服务元件、系统管理元件等。&#10;·物理架构、软件元件是怎样放到硬件上的。&#10;比如下面这张物理架构图描述了一个分布于北京和上海的分布式系统的物理架构，图中所有的元件都是物理设备，包括网络分流器、代理服务器、WEB服务器、应用服务器、报表服务器、整合服务器、存储服务器、主机等等。&#10;图3、一个物理架构的例子 ·系统架构、系统的非功能性特征，如可扩展性、可靠性、强壮性、灵活性、性能等。&#10;系统架构的设计要求架构师具备软件和硬件的功能和性能的过硬知识，这一工作无疑是架构设计工作中最为困难的工作。&#10;此外，从每一个角度上看，都可以看到架构的两要素：元件划分和设计决定。 首先，一个软件系统中的元件首先是逻辑元件。这些逻辑元件如何放到硬件上，以及这些元件如何为整个系统的可扩展性、可靠性、强壮性、灵活性、性能等做出贡献，是非常重要的信息。&#10;其次，进行软件设计需要做出的决定中，必然会包括逻辑结构、物理结构，以及它们如何影响到系统的所有非功能性特征。这些决定中会有很多是一旦作出，就很难更改的。&#10;根据作者的经验，一个基于数据库的系统架构，有多少个数据表，就会有多少页的架构设计文档。比如一个中等的数据库应用系统通常含有一百个左右的数据表，这样的一个系统设计通常需要有一百页左右的架构设计文档。       构架描述       为了讨论和分析软件构架，必须首先定义构架表示方式，即描述构架重要方面的方式。在 Rational Unified Process 中，软件构架文档记录有这种描述。&#10;构架视图       我们决定以多种构架视图来表示软件构架。每种构架视图针对于开发流程中的涉众（例如最终用户、设计人员、管理人员、系统工程师、维护人员等）所关注的特定方面。&#10;      构架视图显示了软件构架如何分解为构件，以及构件如何由连接器连接来产生有用的形式 [PW92]，由此记录主要的结构设计决策。这些设计决策必须基于需求以及功能、补充和其他方面的约束。而这些决策又会在较低层次上为需求和将来的设计决策施加进一步的约束。&#10;典型的构架视图集       构架由许多不同的构架视图来表示，这些视图本质上是以图形方式来摘要说明“在构架方面具有重要意义”的模型元素。在 Rational Unified Process 中，您将从一个典型的视图集开始，该视图集称为“4+1 视图模型”[KRU95]。它包括： 用例视图：包括用例和场景，这些用例和场景包括在构架方面具有重要意义的行为、类或技术风险。它是用例模型的子集。 逻辑视图：包括最重要的设计类、从这些设计类到包和子系统的组织形式，以及从这些包和子系统到层的组织形式。它还包括一些用例实现。它是设计模型的子集。 实施视图：包括实施模型及其从模块到包和层的组织形式的概览。 同时还描述了将逻辑视图中的包和类向实施视图中的包和模块分配的情况。它是实施模型的子集。 进程视图：包括所涉及任务（进程和线程）的描述，它们的交互和配置，以及将设计对象和类向任务的分配情况。只有在系统具有很高程度的并行时，才需要该视图。在 Rational Unified Process 中，它是设计模型的子集。 配置视图：包括对最典型的平台配置的各种物理节点的描述以及将任务（来自进程视图）向物理节点分配的情况。只有在分布式系统中才需要该视图。它是部署模型的一个子集。 构架视图记录在软件构架文档中。您可以构建其他视图来表达需要特别关注的不同方面：用户界面视图、安全视图、数据视图等等。对于简单系统，可以省略 4+1 视图模型中的一些视图。&#10;      构架重点       虽然以上视图可以表示系统的整体设计，但构架只同以下几个具体方面相关： 模型的结构，即组织模式，例如分层。 基本元素，即关键用例、主类、常用机制等，它们与模型中的各元素相对。 几个关键场景，它们表示了整个系统的主要控制流程。 记录模块度、可选特征、产品线状况的服务。       构架视图在本质上是整体设计的抽象或简化，它们通过舍弃具体细节来突出重要的特征。在考虑以下方面时，这些特征非常重要：&#10;系统演进，即进入下一个开发周期。 在产品线环境下复用构架或构架的一部分。 评估补充质量，例如性能、可用性、可移植性和安全性。 向团队或分包商分配开发工作。 决定是否包括市售构件。 插入范围更广的系统。 构架模式       构架模式是解决复发构架问题的现成形式。构架框架或构架基础设施（中间件）是可以在其上构建某种构架的构件集。许多主要的构架困难应在框架或基础设施中进行解决，而且通常针对于特定的领域：命令和控制、MIS、控制系统等等。&#10;构架模式示例&#10;      [BUS96] 根据构架模式最适用的系统的特征将其分类，其中一个类别处理更普遍的结构问题。下表显示了 [BUS96] 中所提供的类别和这些类别所包含的模式。&#10;类别 模式 结构 层 管道和过滤器 黑板 分布式系统 代理 交互系统 模型-视图-控制器 表示-抽象-控制 自适应系统 反射 微核       软件构架是一个容易理解的概念，多数工程师（尤其是经验不多的工程师）会从直觉上来认识它，但要给出精确的定义很困难。特别是，很难明确地区分设计和构架：构架属于设计的一方面，它集中于某些具体的特征。&#10;      在“软件构架简介”中，David Garlan 和 Mary Shaw 认为软件构架是有关如下问题的设计层次：“在计算的算法和数据结构之外，设计并确定系统整体结构成为了新的问题。结构问题包括总体组织结构和全局控制结 构；通信、同步和数据访问的协议；设计元素的功能分配；物理分布；设计元素的组成；定标与性能；备选设计的选择。”[GS93]&#10;       但构架不仅是结构；IEEE Working Group on Architecture 把其定义为“系统在其环境中的最高层概念”[IEEE98]。构架还包括“符合”系统完整性、经济约束条件、审美需求和样式。它并不仅注重对内部的考虑， 而且还在系统的用户环境和开发环境中对系统进行整体考虑，即同时注重对外部的考虑。&#10;      在 Rational Unified Process 中，软件系统的构架（在某一给定点）是指系统重要构件的组织或结构，这些重要构件通过接口与不断减小的构件与接口所组成的构件进行交互。&#10;为阐明其含义，下面将详述其中的两个；完整说明请参见 [BUS96]。模式以下列广泛使用的形式来表示：&#10;模式名 环境 问题&#10;影响，描述应考虑的不同问题方面 解决方案&#10;基本原理 结果环境 示例 模式名&#10;层&#10;环境&#10;需要进行结构分解的大系统。&#10;问题&#10;必须处理不同抽象层次的问题的系统。例如：硬件控制问题、常见服务问题和针对于不同领域的问题。最好不要编写垂直构件来处理所有抽象层次的问题。否则要在不同的构件中多次处理相同的问题（可能会不一致）。&#10;影响&#10;系统的某些部分应当是可替换的 构件中的变化不应波动 相似的责任应归为一组 构件大小 — 复杂构件可能要进行分解 解决办法&#10;将系统分成构件组，并使构件组形成层叠结构。使上层只使用下层（决不使用上层）提供的服务。尽量不使用非紧邻下层提供的服务（不跳层使用服务，除非中间层只添加通过构件）。&#10;示例：&#10;1. 通用层&#10;严格的分层构架规定设计元素（类、构件、包、子系统）只能使用下层提供的服务， 服务可以包括事件处理、错误处理、数据库访问等等。 相对于记录在底层的原始操作系统级调用，它包括更明显的机制。&#10;2. 业务系统层&#10;上图显示了另一个分层示例，其中有垂直特定应用层、水平层和基础设施层。注意：此处的目标是采用非常短的业务“烟囱”并实现各种应用程序间的通用性。 否则，就可能有多个人解决同一问题，从而导致潜在的分歧。&#10;有关该模式的深入讨论，请参见指南：分层。&#10;模式名&#10;黑板&#10;环境&#10;没有解决问题的确定方法（算法）或方法不可行的领域。例如 AI 系统、语音识别和监视系统。&#10;问题&#10;多个问题解决顾问（知识顾问）必须通过协作来解决他们无法单独解决的问题。各顾问的工作结果必须可以供所有其他顾问访问，使他们可以评估自己是否可以参与解决方案的查找并发布其工作结果。&#10;影响&#10;知识顾问参与解决问题的顺序不是确定的，这可能取决于问题解决策略 不同顾问的输入（结果或部分解决方案）可能有不同的表示方式 各顾问并不直接知道对方的存在，但可以评估对方发布的工作 解决办法&#10;多名知识顾问都可访问一个称为“黑板”的共享数据库。黑板提供监测和更新其内容的接口。控制模块/对象激活遵循某种策略的顾问。激活后，顾问查看黑板，以确定它是否能参与解决问题。如果顾问决定它可以参与，控制对象就可以允许顾问将其部分（或最终）解决方案放置于黑板上。&#10;示例：&#10;以上显示了使用 UML 建模的结构或静态视图。 它将成为参数化协作的一部分，然后会绑定到实参上对模式进行实例化。&#10;构架风格 软件构架（或仅是构架视图）可以具有名为构架风格 的属性，该属性减少了可选的形式，并使构架具有一定程度的一致性。样式可以通过一组模式或通过选择特定构件或连接器作为基本构件来定义。对给定系统，某些 样式可作为构架描述的一部分记录在构架风格指南（Rational Unified Process 中设计指南文档的一部分）中。样式在构架的可理解性与完整性方面起着主要的作用。&#10;构架设计图 构架视图的图形描述称为构架设计图。对于以上描述的各种视图，设计图由以下统一建模语言图组成 [UML99]： 逻辑视图：类图、状态机和对象图。 进程视图：类图与对象图（包括任务 – 进程与线程）。 实施视图：构件图。 部署视图：配置图。 用例视图：用例图描述用例、主角和普通设计类；顺序图描述设计对象及其协作关系。 构架设计流程 在 Rational Unified Process 中，构架主要是分析设计工作流程的结果。当项目再次进行此工作流程时，构架将在一次又一次迭代中不断演化、改进、精炼。由于每次迭代都包括集成和测试，所以在交付产品时，构架就相当强壮了。构架是精化阶段各次迭代的重点，构架的基线通常会在此阶段结束时确定。&#10;架构师&#10;软体设计师中有一些技术水平较高、经验较为丰富的人，他们需要承担软件系统的架构设计，也就是需要设计系统的元件如何划分、元件之间如何发生相互作用，以及系统中逻辑的、物理的、系统的重要决定的作出。&#10;这样的人就是所谓的架构师（Architect）。在很多公司中，架构师不是一个专门的和正式的职务。通常在一个开发小组中，最有经验的程序员会负责一些架构方面的工作。在一个部门中，最有经验的项目经理会负责一些架构方面的工作。&#10;但是，越来越多的公司体认到架构工作的重要性，并且在不同的组织层次上设置专门的架构师位置，由他们负责不同层次上的逻辑架构、物理架构、系统架构的设计、配置、维护等工作。 卡内基梅隆大学软件研究所关于软件架构的定义&#10;</description></item><item><title>Hash 算法及其应用</title><link>https://hessian.cn/p/314.html</link><pubDate>Sat, 05 May 2007 04:21:00 +0800</pubDate><guid>https://hessian.cn/p/314.html</guid><description>什么是 Hash Hash 的重要特性 Hash 函数的实现 主要的 Hash 算法 Hash 算法的安全问题 Hash 算法的应用 结 论 Hash， 一般翻译做“散列”，也有直接音译为"哈希"的，就是把任意长度的输入（又叫做预映射， pre-image），通过散列算法，变换成固定长度的输出，该输出就是散列值。这种转换是一种压缩映射，也就是，散列值的空间通常远小于输入的空间，不 同的输入可能会散列成相同的输出，而不可能从散列值来唯一的确定输入值。&#10;</description></item></channel></rss>