<!-- /* Font Definitions */ @font-face {font-family:宋体; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-alt:SimSun; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} @font-face {font-family:"Cambria Math"; panose-1:2 4 5 3 5 4 6 3 2 4; mso-font-charset:1; mso-generic-font-family:roman; mso-font-format:other; mso-font-pitch:variable; mso-font-signature:0 0 0 0 0 0;} @font-face {font-family:Calibri; panose-1:2 15 5 2 2 2 4 3 2 4; mso-font-charset:0; mso-generic-font-family:swiss; mso-font-pitch:variable; mso-font-signature:-1610611985 1073750139 0 0 159 0;} @font-face {font-family:"/@宋体"; panose-1:2 1 6 0 3 1 1 1 1 1; mso-font-charset:134; mso-generic-font-family:auto; mso-font-pitch:variable; mso-font-signature:3 135135232 16 0 262145 0;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal {mso-style-unhide:no; mso-style-qformat:yes; mso-style-parent:""; margin:0cm; margin-bottom:.0001pt; text-align:justify; text-justify:inter-ideograph; mso-pagination:none; font-size:10.5pt; mso-bidi-font-size:11.0pt; font-family:"Calibri","sans-serif"; mso-ascii-font-family:Calibri; mso-ascii-theme-font:minor-latin; mso-fareast-font-family:宋体; mso-fareast-theme-font:minor-fareast; mso-hansi-font-family:Calibri; mso-hansi-theme-font:minor-latin; mso-bidi-font-family:"Times New Roman"; mso-bidi-theme-font:minor-bidi; mso-font-kerning:1.0pt;} p {mso-style-noshow:yes; mso-style-priority:99; mso-margin-top-alt:auto; margin-right:0cm; mso-margin-bottom-alt:auto; margin-left:0cm; mso-pagination:widow-orphan; font-size:12.0pt; font-family:宋体; mso-bidi-font-family:宋体;} .MsoChpDefault {mso-style-type:export-only; mso-default-props:yes; mso-bidi-font-family:"Times New Roman"; mso-bidi-theme-font:minor-bidi;} /* Page Definitions */ @page {mso-page-border-surround-header:no; mso-page-border-surround-footer:no;} @page Section1 {size:612.0pt 792.0pt; margin:72.0pt 90.0pt 72.0pt 90.0pt; mso-header-margin:36.0pt; mso-footer-margin:36.0pt; mso-paper-source:0;} div.Section1 {page:Section1;} -->
阿三看到一个非常有兴趣的网页, 想把它保存下来, 于是, 阿三点击" 文件-> 另存为", 选择" 网页, 全部(*.htm,*.html)".
OK, 阿三的硬盘上多了一个a.html 文件和一个a 文件夹, 里面保存了这个网页上的所有资源, 图片,css,js 一大堆. 阿三看着这一大堆文件, 想整理又不太方便, 于是阿三打电话给Axman," 大哥, 我能不能把当前网页保存为一个文件又能显示原来的效果啊?"Axman 晕了半天, 没敢吱声, 心想这世上竟然有人能笨到这样, 也算没白活了. 但没敢说出来, 因为Axman 欠了阿三几万块钱, 所以阿三再笨, 一有问题Axman 就会马上就会给他解答. 于是Axman 那种冷艳的来自于原古冰河纪的声音在电话另一端响起:" 阿三啊, 你应该这样, 文件-> 另存为, 选择Web 档案, 单一文件(*.mht), 这样就会存为一个复合文档".
" 啊, 大哥, 原来这样啊, 复合文档是不是就是多种格式的文档被压在一起的啊?"
" 是啊, 这样浏览器解释时就可以把复合文档分解开来重新显示".
" 啊, 我知道了,Word 也是这样".
" 轰!",Axman 晕倒时, 激起千重浪~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
" 那叫结构化文档, 算了跟你说你也不懂."
边上Axman 养了多年的浣熊多多不停地跳来跳去, 这家伙的聪灵程度不可小视, 几年下来写个小程序已经不在话下, 加上聪明好学, 对什么都非常好奇, 深得Axman 的宠爱.
多多听了阿三和Axman 的对话, 不住好奇地问道:" 主人, 什么是复合文档, 什么是结构话文档呢"?
Axman 换了一种慈祥的语气, 缓缓道来.......
复合文档就是在一个文档中以设定的boundary 来分隔多个文档, 不同类型的文档在以boundary 为分隔符的区域内以特定方式编码为可视
的文本文件, 在应用程序解释复合文档时再根据boundary 和编码规则还原成多种文档然后由同一应用程序解释.
但是复合文档有一个缺点就是不能被多个应用程序同时打开, 而且一般而言可写性极差, 因为事实上它是被编码后以文本形式顺序存储的,
所以当一个应用将该档载入内存后, 如果其它应用程序再重写其中的内容, 两个应用程序访问的内容就会发生冲突.
而结构化文档从存储模型上而言, 类似于目录形式, 在目录中可以有子目录和文件, 在结构化文档中叫子存储和流. 这种存储形式最大的好处
就是不同应用程序可以同时访问同一结构化文档的不同部分, 就象访问同一个文件系统中不同目录下的文件一样不会发生任何冲突.
多多听得似懂非懂, 眨眨眼睛又问: 那它和您要说的OLE 有什么联系呢?
结构化文档的概念才会有后来的OLE 的出现, 在此基础才有组件, 从local CALL 到RPC, 到SOA, 这些技术的出现都因为有解决结构化文档
的初衷.MS office 在这个历史发展中起着不可磨灭的伟大作用.
最先,MS 的一批牛人开发了MS WORD 这个东西, 它的功能性和易用性一下子把中国流行了十多年的WPS 踢出了峨眉山顶, 关且从此再也没有爬起来过. 这批牛人不仅有牛的技术, 更有牛的理念, 这一点WPS 连提鞋的水平都不能比. 他们在设计出WORD 的同时, 还同时设计出excel,powerpoint 等office 套件, 最关键的是, 他们成功地解决了在套件中每个应用程序之间的功能调用. 比如在一个word 文档中, 如果要插入excel 表格, 一般人的思想就是把电子表格的逻辑COPY 到WORD 中, 也就是解释Wrod 中必须有解释电子表格的功能代码. 但MS 的牛人们并没有这么做, 而是利用结构化文档的功能将电子表格存为doc 文件中的一个子存储, 并在其中存储了用什么应用程序来解释的一段编码, 在windows 中csid, 根据它就能从注册表中找到要解释这个子存储中的流的应用程序. 这样其实结构化文档可以存储任何其它应用程序能处理的内容.
这样, 具有单一功能的" 组件"( 这时还没有叫组件, 但我现在就提前用组件这个词, 因为当前叫什么我也不知道), 就可以被其它应用程序多次重复地调用, 使单个组件能够组成具有复杂功能的系统.MS 的牛人开始把多个应用不断地用local CALL 方式调用其它组件的模型修改成组件服务
模型, 即把有某个功能的组件发布成服务, 其它应用程序要调用组件的功能, 只要向这个系统服务提供相应的参数就行了, 而应用程序本身根本. 不必关心它所存储和访问的子存储是什么内容, 以及如何处理. 要做的是仅仅向组件提供基础的存诸访问API 环境即基础输入输出. 组件自身就可以完全处理应用程序指定要处理的内容.
虽然OLE 最后被发展成COM,COM+,REMOTING, 但最初它确实是为了解决office 套件中功能的互调用的. 把功能相对完善, 稳定且被多次访问的部分独立出来发布为服务. 加上对服务访问的协议和控制, 就演变成了组件模式.
组件模型的改变功能的调用边界从的locall API CALL 变成了异构访问. 举个最简单的例子, 操作系统命令如果单单实现一段程序, 那么它只能被以API 方式去连结, 但系统命令通过shell 这个容器被发布成了一个服务, 那么它在系统中可就以被多种能进行shell 调用的编程语言所调用. 而完成相同的功能, 实上这就是弱化模型的组件服务.
多多忍不住拍手称赞, 太好了, 太好了, 这样以后大家都方便了.
Axman 摸了摸多多的头:" 多多, 你太善良了, 事实并不象你想的那样."
这世界就是如此, 任何事情都具有相对性, 人类社会中, 有些人本来就是一个P(person), 但一旦给了他们一个特定的名称, 比如把他们叫官员时, 让他们提供相应的服务就不是寻么容易的事了." 组件" 本质上只是完成些特定功能的代码, 但现在它的位置升到了组件, 要想让它服务, 你就要遵循一定的协议, 这些协议规定了访问组件的很多接口.
在MS 这个领土上, 即使是MS 家族的贵族成员VC/VB 要访问这些组件也要通过IUnknow,IDispatch 这些接口, 加上令有头晕的UUID 之类不是人能理解的参数之类复杂的关系和手续才能让" 组件" 为你服务. 在java 领土上你通过复杂的EJB 访问协议来让组件为你服务. 其复杂程度不是你能想象的. 比如: 我上次要去交480 块钱的车船税, 却要以请一天假( 扣掉1500 大洋) 的代价来向通州地税这个组件请求服务, 因为这个组件周末不上班.
后来组件调用者不乐意了, 他们向" 组织" 提意见了, 要求提供功能的组件应该有统一的方便的调用接口, 我们只要向这个接口提供足够的信息, 组件就应该提供服务, 这些接口不能耦合于某一特定环境, 能接受外国人, 本地人这些不同类型的人的相同请求. 于是" 组织" 让组件们把自己包装成WEB 服务. 任何调用者只要通过http 连结发送定义好的文档, 组件就提供服务. 组织发现有一种叫SOAP 的东西正好能完成这样的通讯, 而不同国家不同种类的调用者也乐意使用这样协议, 于是大家都过统一的WEB 服务模型来向请求服务, 至于他是如何提供服务的调用者并不关心, 这下一来确实方便多了.
SOA 从本质上并不复杂, 它只是组件调用方式网络化的一种设计思想, 并不是指具体的实现技术. 在此之前已经很多" 概念" 实现了这个功能, 把一定功能的组件加上网络的功能, 这可以把调用的边界从同一机器扩展到机器间调用, 这从设计上其实扩大通用的功能共享范围. 加上调用协议的控制使调用更新方便灵活. 这种" 方便为民的思想" 确实不仅给调用者带来方便, 而且给服务提供者也带来了方便, 同一套组件作为WEB 服务方式发布可以为所有能访问该WEB 服务器的人提供服务( 这里不涉及安全讨论), 从" 组织" 的观点看提了机构的工作效率, 而且得到调用者的好评, 于是" 组织" 把这种模式提高为" 为人民服务" 的思想, 英文名就叫"SOA". 我们以前设计系统是以功能为着眼点, 用户要什么我们就给什么, 现在, 我们以服务为主, 我们有很多专业的服务队伍发布在多个服务器上, 当你需要服务时就来访问我们. 这就是SOA 的本质.
Axman 回头看了看多多, 多多已经流着口水要打酣了......................
几句重要的话:
SOA 是一种设计思想,Web Service 是SOA 的一种实现手段.( 意味着你可以不用Web Service 来实现SOA, 只要你的架构符合SOA 思想)
SOA 不是灵丹妙药, 不是所有系统架构都适合SOA 的, 比如无远程调用和分布式应用的桌面应用系统, 这样的系统使用SOA 的唯一好处就是让你的系统变慢.
SOA 是早已存在的思想, 只是近来又被一些厂商拿出来包装一下, 所以它是经济产物而不是技术产物.