`

从银行WebService报文接口系统中,学习敏捷设计

阅读更多

Preface:

 

合理的软件架构设计其好处是不言而喻的,系统具有清晰的软件结构,良好的可扩展性,类的职能单一明确,系统的复杂度底。此前的一个实际项目中总结了些关于OO设计的实际应用,主要是围绕‘高内聚及松耦合’,‘开闭原则’的一些应用。

 

Problem:

 

目前有一个实际应用放在我们面前,为一个银行现有BI系统开发WebService对外数据接口应用,数据交换方式以预定请求及响应报文来完成,要求可以数据接口系统跨平台使用。即远程客户端发来一种XML数据请求报文,系统按类型执行查询,然后返回XML数据响应报文。

 

问题也浮出水面,通常此类系统中我们可以想像到,其中一定会有一系列的if else来判断是何种请求报文,然后再执行对应的动作,但我们如果我们这样设计,系统就违反了开放-封闭原则 (OCP,Open-Close Principle),日后的扩展一定需要修改原有代码,而我们期望的是日后添加一种新报文后,只在系统中扩展新的请求、查询及响应对象来实现新需求。

 

带着问题思考解决办法...

 

补充:敏捷设计扩展知识手册

 

拙劣设计的症状:

 

1.僵化性(Rigidity):设计难以改变。很难对系统进行改动,因为每个改动都会迫使许多对系统其他部分的其他改动。

2.脆弱性(Fragility):设计易于遭到破坏。对系统的改动会导致系统中和改动的地方在概念上无关的许多地方发现问题。3.牢固性 (Immobility):设计难以重用。很难解开系统的纠结,使之成为一些可在其他系统中重用的组件。

4.粘滞性(Viscosity):难以做正确的事情。做正确的事情比做错误的事情要困难。

5.不必要的复杂性(Needless Complexity):过分设计。设计中包含有不具有任何直接好处的基础结构。

6.不必要的重复性(Needlsee Repetition):滥用复制/粘贴。设计中包含有重复的结构,而该重复的对象本可以使用单一的抽象进行统一。

7.晦涩性(Opacity):很难阅读、理解。没有很好的表现出意图。

 

 

面向对象的设计原则:

 

1.单一职责原则 (SRP,Single Resposibility Principle)

2.开放-封闭原则 (OCP,Open-Close Principle)

3.Liskov替换原则 (LSP,Liskov Principle)

4.依赖倒置原则 (DIP,Dependicy Independent Priciple)

5.接口隔离原则 (ISP,Interface Seperation Principle)

 

Solution:

 

我们初步的想法是,系统接受到一种XML请求后将其转换成请求对象,类似多态的方法,根据不同的请求对象由查询工厂来创建返回不同的查询处理类,再由查询处理类返回填充好的数据响应对象,最后转换成XML响应报文。由此思路,我们完成了UML类图设计,如下:

 

 

 

首先是RemoteQueryService 接口,系统对外的WS服务由此接口完成。

 

/**
 * 类说明: WS远程服务接口<br>
 * 创建时间: 2009-11-6 上午10:07:55<br>
 * 
 * @author Seraph<br>
 * @email seraph115@gmail.com<br>
 * 
 */
public interface RemoteQueryService {

	/**
	 * 功能说明: <br>
	 * 创建者: Seraph<br>
	 * 创建时间: 2009-11-6 上午10:08:09<br>
	 * 
	 * @param request
	 * @return
	 */
	@Profiled(tag = "RemoteQueryService")
	public String doQuery(String request);

}

 

RemoteQueryServiceImpl 类是此接口的实现,接口方法为接受一种XML请求报文然后返回响应报文。

RegisterContainer 类,在系统初始化时完成不同请求所对应的查询处理类的注册。

QueryFactory 类,根据不同的请求对象返回不同的查询处理类。

ParserRobot 类,负责将XML请求转换为Java请求对象,将Java响应对象转换为XML报文。

QueryProvider 抽象类,是不同种查询处理类的父类。

Request 类,是请求对象的父类。

Response 类,是响应对象的父类。

 

其中QueryProvider 类,doQuery抽象方法由继承后的子类实现,用来实现不同种报文的查询处理方法,代码为:

/**
 * 类说明: <br>
 * 创建时间: 2009-11-6 上午10:21:30<br>
 * 
 * @author Seraph<br>
 * @email seraph115@gmail.com<br>
 * 
 */
@Service
public abstract class QueryProvider {

	private QueryDaoSupport queryDaoSupport;

	private SqlProvider sqlProvider;

	public abstract Response doQuery(Request request) throws BrwsException;

	public QueryDaoSupport getQueryDaoSupport() {
		return queryDaoSupport;
	}

	public void setQueryDaoSupport(QueryDaoSupport queryDaoSupport) {
		this.queryDaoSupport = queryDaoSupport;
	}

	public SqlProvider getSqlProvider() {
		return sqlProvider;
	}

	public void setSqlProvider(SqlProvider sqlProvider) {
		this.sqlProvider = sqlProvider;
	}

}
 

由UML图中,我们可以看到Request , QueryProvider , Response有许多对应的子类,而每个子类都是一种报文类型,也就是系统所能提供的查询服务。所以目前的架构设计下,日后添加一种新报文将很容易,只需要实现一组 Request, QueryProvide及 Response就可以完成新报文的实现,从而达到了松耦合、可扩展的设计。

 

 

 

 

 

 

 

 

分享到:
评论
35 楼 wenfuchang 2011-03-04  
银行项目进度很紧,通常关注业务的时间远比关注技术实现的时间多很多,所以很多实现是拿来主义。

以前的汇票项目通过一个“中间代理平台”调用核心记账接口,规定使用WS与“中间代理平台”通讯。

另外一个项目使用XML-RPC,没有跨语言需求

还有一个是http+XML,XML是业务数据
34 楼 andot 2010-04-13  
lz的第1条原因说的很对,有时候是硬性要求,这个没办法。但客户可能认为SOAP就是XML,并不知道自己再定义XML就等于XML套XML这个事实。客户对一些概念可能只是大概有个模糊认识,具体应该怎么用他们可能并不清楚,所以提出一些外行的设计要求是在所难免的,在不伤及客户脸面的情况下,引导客户往正确的方向走,对自己对客户都有好处。如果一味的迁就客户,可能最后不但自己工作量大,做出的东西客户也不一定就满意。就好像一个理发师,在给客人理发时是不能完全听凭客人摆布的,否则理出的发型可能惨不忍睹。

不过楼主说的第2条理由的前提是调用只能传递简单类型参数。但如果可以传递复杂类型参数的话,还是以参数传递方式比较清楚,比传递XML清楚的多。也就是说当参数仅为1-3个简单类型参数时,就按照顺序传入即可。当参数为很多简单类型参数时,甚至个数不确定的时候,用对象、数组或集合(或者它们的嵌套组合)作为参数传入效果更好。例如:

addUser(User user);

远比:
addUser(String name, int age, Sex sex, bool married...);

或者:
addUser(String xml);

的好。

简单的说:远程调用接口跟本地调用接口使用相同的设计原则即可。无需将远程调用接口XML化。
33 楼 Seraph115 2010-04-13  
andot 写道
hatedance 写道
我请问lz,你喜欢哪个?
login(String userId,String password);


String xml ="<request><parameter name="userId">foo</parameter><parameter name="password">bar</parameter></request>";
login(String xml);


我喜欢
login(String userId,String password);


我想lz从内心里也是喜欢这个,但是为了面子,他可能会选择:
String xml ="<request><parameter name="userId">foo</parameter><parameter name="password">bar</parameter></request>";
login(String xml);

而且会为了显示自己有充分的理由,会在后面说出一些完全没有道理的道理来。


楼上的2条解释是我的道理,还有我举这个实例是想讲解如何解构,和设计方法

32 楼 Seraph115 2010-04-13  
hatedance 写道
我请问lz,你喜欢哪个?
login(String userId,String password);


String xml ="<request><parameter name="userId">foo</parameter><parameter name="password">bar</parameter></request>";
login(String xml);


大家好,我才是lz,‘JE帐号’小盆友被大家误认了 

1.使用xml作为数据传输方式是因为银行对外业务接口确定为xml报文形式,也就是客户方的要求,这个是项目签订时所定,另外银行内多套系统间都使用xml报文形式,相当于一种契约,这个我相信大家都能理解,作为项目经理也没有必要在这个需求上引导客户。

2.如果是简单的参数请求我当然喜欢第一个,不过这里是个请求报文的简单例子,其中accountid可以有很多,在函数实现时传入大于5个以上参数时,调用方也很麻烦,因为需要知道参数顺序

<request>
  <service>accountype</service>
  <type>0</type>
  <trandate>20080111</trandate>
  <data>
  <items>
    <item>
      <accountid>6601060000026</accountid>
      <accountid>32432432424</accountid>
    </item>
  </items>
  </data>
</request>


要是

login(String service, int type, String trandate, String[] accountids);


String xml ="<request><service>accountype</service><type>0</type><trandate>20080111</trandate><data><items><item><accountid>6601060000026</accountid><accountid>32432432424</accountid></item></items></data></request>";
login(String xml);


你喜欢那个呢?

31 楼 andot 2010-04-09  
JE帐号 写道
andot 写道
hatedance 写道
我请问lz,你喜欢哪个?
login(String userId,String password);


String xml ="<request><parameter name="userId">foo</parameter><parameter name="password">bar</parameter></request>";
login(String xml);


我喜欢
login(String userId,String password);


我想lz从内心里也是喜欢这个,但是为了面子,他可能会选择:
String xml ="<request><parameter name="userId">foo</parameter><parameter name="password">bar</parameter></request>";
login(String xml);

而且会为了显示自己有充分的理由,会在后面说出一些完全没有道理的道理来。


1.下次叫别人LZ前,请先确定自己叫的对不对.

2.上面一个帖子,你说http很多年未变,恰恰是我更推崇传递简单值对象的原因.如果你觉得因为http协议基本没有大的改变就认为http多年没什么变化,那真是笑死人了.web前端技术,后端技术这些年变化有多大,地球人都知道.可是在这种剧烈的变动中,web开发依然能保持一个稳定的发展,不就因为协议上的简单稳定么?我只能说,看到你的回复,越发的让我坚定能不用远程对象调用就不用远程对象调用的决心.

3.至于什么xml套xml,你觉得丑陋,可我觉得有用就好了.我用已有soap的框架帮我建立连接传输数据,我觉得方便.但是我觉得他对数据定义方面的要求我不喜欢,所以我就按自己喜欢的方式来.这就叫实践.难道你用Struts的时候就是他定义的任何规范和组件都使用么?

4.至于什么死不承认,说说以前的经历就是死不承认,我好怕啊,这帽子盖的.我只不过看到有人说ws就说说自己的看法.你觉得ws不好,我也觉得现在ws现在不是最好选择,但是觉得没必要太过鄙视ws,ws设计成那个样子是有原因的.它的主要目的是在解决跨语言调用,有点取代更难用的cobra的意思.你说的什么兼容多种语言的轻量级远程调用框架,这样确实高效,可是你给一个语言一个语言去写实现,而且还会带来对项目的侵入和绑定.ws只不过换另外一个思路,定义个中立语言好了,我不负责兼容别人,别人来兼容我吧.我们这些xml套xml的人就更懒了,连中立语言都不想学,直接用基本什么语言都能识别的xml吧.这只是个思路的不同而已,我是实在看不出什么对错之分.... 再说了,我也不是没用过类似你说的,我们一个实效性要求很高的模块,就是采用google的Protocol Buffers,感觉也很好啊.是不是夸一个非要去贬低另外一个啊?

5.最后回答一下那个喜欢哪个的问题.我当然喜欢login(String userId,String password);了.但是很可惜的是,即便是传xml方式我也是这样调用的.难道真的有人在调用函数的时候拼xml?我是不信DI.协议解析层和业务层不会混成这样吧.



1、lz这两个字母我是接的hatedance的,请先看明白我回答的是谁,然后再插嘴,不要自作多情的把lz往自己身上套。

2、我说的就是http协议多年未变,我什么时候说过“web前端技术,后端技术这些年”没有变化了?你没看到我说的是“使用它的人的思维在改变,在它之上构建的其它技术在发展”吗?你是不是只看前言不看后语啊,难怪你理解事物总是那么片面,使用技术只取其形而未领其意呢,原来是你一直有这种只看前一半文字,而后一般文字完全靠自己杜撰的习惯啊。

3、你前面说坚持不用远程对象调用,可是这里你又坚持用soap套自定义XML,这就很有点自相矛盾了。soap设计出来就是用于实现远程调用的,你既然不用,你就直接用http+xml啊,弄个soap套xml不伦不类的,所以说你坚持的不是简单,而是坚持的滥用。我也不期望我的话能改变你的看法,我没那个本事,我只是希望你不要去用自己的错误实践去误导别人。至于你过去,现在还是将来怎么用,那都是你自己的事情。

4、你说的ws设计出来的“主要目的是在解决跨语言调用,有点取代更难用的cobra的意思”这句话一点都没错,这是ws设计的目的,可是最后的实现ws却把自己变成了一个跟cobra一样难用的东西。“ws只不过换另外一个思路,定义个中立语言好了,我不负责兼容别人,别人来兼容我吧”,你以为ws只要设计出来不用实现就可以用吗?这是不可能的。或者你认为上帝会帮你实现好?这是更不可能的!ws跟其它远程调用技术一样,都需要一个语言一个语言去写实现,每种ws实现也都会带来对项目的侵入和绑定,而且事实上目前ws的复杂程度已经让在各个语言上去实现的难度远远超过其它远程调用技术的实现,这也是为什么只有Java、.NET这些有大厂商后台的语言平台上有比较好用的ws实现(但也仅限于在自己的平台上好用,与其它平台和语言的互通性并不好,这是因为这些大厂商们在自己的实现中都加入了自己特有的东西,这样做是为了构建技术壁垒,所以即使有统一的协议,也不意味着就有统一实现),而其它一些脚本语言上只有一些功能不全互通性差的三流实现(这些三流实现不能良好互通就完全是因为没有足够的技术实力来实现定义如此复杂的ws造成的啦)。我想你根本就不了解ws与其它远程调用技术的本质,才会说出这样一套区别ws和其它远程调用技术的错误理论来。ws和soap是个失败的设计,这个结论不是我个人下的,在《Joel谈优秀软件开发方法》一书中,你会发现说出这个事实的恰恰是一些程序设计大师。另外,你说的Protocol Buffers并不是一种远程调用技术,Protocol Buffers本质上只是一个数据序列化方案,你可以认为他跟XML是一样的东西,都是用来表示数据的。它本身并不包含远程调用的定义,因此基于Protocol Buffers这种数据序列化表示方案的远程调用并不存在统一的定义和实现,不同的远程调用过程中因为走的调用协议不同,所以尽管采用相同的数据表示,仍然不能互通。

5、既然有 login(String userId,String password); 这样的统一接口,至于后面的数据表示采用什么是无所谓的。xml格式也好、Protocol Buffers格式也好、其它序列化格式也好都是一样的。只要采用相同的远程调用协议,就可以实现互通,完全没有必要自己绑死在XML上。另外,hatedance这个问题是问lz的,因为lz的例子里面就是后面那种在调用函数的时候拼xml的方式,所以,你不相信的事情就是lz干的。
30 楼 JE帐号 2010-04-09  
andot 写道
hatedance 写道
我请问lz,你喜欢哪个?
login(String userId,String password);


String xml ="<request><parameter name="userId">foo</parameter><parameter name="password">bar</parameter></request>";
login(String xml);


我喜欢
login(String userId,String password);


我想lz从内心里也是喜欢这个,但是为了面子,他可能会选择:
String xml ="<request><parameter name="userId">foo</parameter><parameter name="password">bar</parameter></request>";
login(String xml);

而且会为了显示自己有充分的理由,会在后面说出一些完全没有道理的道理来。


1.下次叫别人LZ前,请先确定自己叫的对不对.

2.上面一个帖子,你说http很多年未变,恰恰是我更推崇传递简单值对象的原因.如果你觉得因为http协议基本没有大的改变就认为http多年没什么变化,那真是笑死人了.web前端技术,后端技术这些年变化有多大,地球人都知道.可是在这种剧烈的变动中,web开发依然能保持一个稳定的发展,不就因为协议上的简单稳定么?我只能说,看到你的回复,越发的让我坚定能不用远程对象调用就不用远程对象调用的决心.

3.至于什么xml套xml,你觉得丑陋,可我觉得有用就好了.我用已有soap的框架帮我建立连接传输数据,我觉得方便.但是我觉得他对数据定义方面的要求我不喜欢,所以我就按自己喜欢的方式来.这就叫实践.难道你用Struts的时候就是他定义的任何规范和组件都使用么?

4.至于什么死不承认,说说以前的经历就是死不承认,我好怕啊,这帽子盖的.我只不过看到有人说ws就说说自己的看法.你觉得ws不好,我也觉得现在ws现在不是最好选择,但是觉得没必要太过鄙视ws,ws设计成那个样子是有原因的.它的主要目的是在解决跨语言调用,有点取代更难用的cobra的意思.你说的什么兼容多种语言的轻量级远程调用框架,这样确实高效,可是你给一个语言一个语言去写实现,而且还会带来对项目的侵入和绑定.ws只不过换另外一个思路,定义个中立语言好了,我不负责兼容别人,别人来兼容我吧.我们这些xml套xml的人就更懒了,连中立语言都不想学,直接用基本什么语言都能识别的xml吧.这只是个思路的不同而已,我是实在看不出什么对错之分.... 再说了,我也不是没用过类似你说的,我们一个实效性要求很高的模块,就是采用google的Protocol Buffers,感觉也很好啊.是不是夸一个非要去贬低另外一个啊?

5.最后回答一下那个喜欢哪个的问题.我当然喜欢login(String userId,String password);了.但是很可惜的是,即便是传xml方式我也是这样调用的.难道真的有人在调用函数的时候拼xml?我是不信DI.协议解析层和业务层不会混成这样吧.

29 楼 szwx855 2010-04-08  
我们之前也有一个项目,基本实现如楼主所示,不过有几点不同
1.action有一个基类
2.service有一个基类。
3.dao有一个基类。


action基类用于定义全局map,log4j,等。service基类定义了需要查询的种类,如sql查询、无事务查询、有事务查询,springjdbc/hibernate查询等。而dao层接口只是定义了些service。

这样的话跟楼主思想差不多一样,不过还是学习了。呵呵。
28 楼 andot 2010-04-06  
hatedance 写道
我请问lz,你喜欢哪个?
login(String userId,String password);


String xml ="<request><parameter name="userId">foo</parameter><parameter name="password">bar</parameter></request>";
login(String xml);


我喜欢
login(String userId,String password);


我想lz从内心里也是喜欢这个,但是为了面子,他可能会选择:
String xml ="<request><parameter name="userId">foo</parameter><parameter name="password">bar</parameter></request>";
login(String xml);

而且会为了显示自己有充分的理由,会在后面说出一些完全没有道理的道理来。
27 楼 andot 2010-04-06  
JE帐号 写道
andot 写道
JE帐号 写道
以什么方式传数据,是协议的问题.
数据传过来以后,以什么形式给使用者是应用层问题.
两个不在一个层次上的东西,为什么非要混在一起讨论呢?
所谓轻量级,不是说程序员越轻松就越轻量级.很多轻量级的方案,却对实现有着无比严格的要求和侵入.这样的东西,只轻了自己,一点也没在开放性上考虑.
传xml,你觉得序列化麻烦.那干嘛不用RMI?那还能直接操作远程对象呢.
SOAP的好处从来不是说让你可以在调用一个方法后happy的直接使用一个对象,那根本就不是SOAP所考虑的事情.
最后,虽然现在http很强势,但是还是有很多很多老的系统以及行业,在应用层面不是使用http交换数据,在那些领域SOAP仍然适用.


SOAP本身就是传XML的,而且本身是有标准的。

在SOAP之上再传自定义的XML格式,就等于使用标准的XML封装了非标准的XML。既然这里用了非标准的自定义的XML格式,还有什么开放性可言?明明是你自己根本不理解SOAP是干啥的,还说别人不懂SOAP的好处,这简直就是个笑话。

另外,你这里强调很多很多老的系统以及行业,在应用层面不是使用http而是使用SOAP,我就更要笑话你啦。你说是http出现的早还是SOAP出现的早呢?http从出现到现在都已经20年了,从目前最流行的http1.1算起也有10多年的历史了,在这十多年里,http1.1经历了无数的考验,在其上构建的系统远多于在SOAP之上构建的系统。而SOAP从成为标准到现在还不足10年,最新的SOAP1.2标准距今才只有3年的历史,而且SOAP 1.0、1.1、1.2三个标准的兼容性相当差劲,你还指望使用老版本SOAP协议的系统能跟使用新版本SOAP协议的系统实现互通,这本身就是一个笑话,更何况还要在这个本来就不能很好互通的协议之上再跑一个自定义的非标准的XML,还说这叫开放性,这就是笑话之上的笑话了。http的互通性远比SOAP要好的多,反正都是要交换自定义XML的话,与其再穿上一层XML的外衣,让标准XML套上非标准XML,真的还不如在http上裸奔非标准XML好。

至于你说的为什么要用SOAP而不用RMI传对象,这个道理大家都知道,因为RMI仅限于Java,而SOAP却不是仅限于Java,这跟你说的是不是传对象没有任何关系。所以你这个例子根本证明不了你自己观点。而且要跨平台传输对象,在7年之前,确实SOAP可能是当时最好的选择,但现在来说SOAP已经不是唯一选择,也不是最好的选择了。向PHPRPC、Hprose等新型的高效的跨语言跨平台的远程对象调用的兴起,已经完全可以代替臃肿繁杂的SOAP。所以不管是新系统建设,还是老旧系统的维护,SOAP都没有任何适用的理由了。


1.每个技术都要放在当时的历史环境看.从历史看ws的发展和http的发展根本就是两条线,所以站在现在去简单的批判ws,还拿现在的http来说事,根本就不是一个平等的对比.
2.单就ws来说,之所以那么多实践要在soap的xml内部再嵌套xml.恰恰说明了大家意识到,传输层越简单越好的道理.协议格式与我的业务数据是隔离的,我的业务数据就是一个xml片,至于你的协议是什么,是那个版本,采用什么方式传输都只是我的协议接口实现的问题.从认知的角度,接触到SOAP,觉得麻烦,然后再看到别人好的实践,然后学习到这种"挂羊头卖狗肉"的做法,这就是我的实际学习过程,我只是说出来而已.
3.站在现在看,SOAP还那么有必要么?确实没必要,如你所说,直接http+xml比他还省事,但这是第三个阶段,是一个理解的过程.如同你用惯了现代操作系统,反过头也没必要指责老的操作系统如何如何.
4.http的历史确实很长,但是像现在这样功能越来越强大,涉及领域越来越多从我个人感觉看却只是这几年了功夫,倘若http 10年前就像现在这般无所不能,SOAP也许根本不会出现.
5.SOAP臃肿繁杂并不代表传输简单值对象就不行,远程对象调用也未必真会成主流.如同html一样,传输层越简单越明了越好.这点恐怕很难改变,修改的只是我们使用的具体协议.至于业务的xml片,从未改变过.


1、你说的没错,技术是要放到当时的历史环境看的,所以我前面在比较http和SOAP时,是从20年前一直讲到现在的,并说明了在这个发展过程中http是如何成功以及SOAP是如何失败的。将一个成功的技术和一个失败的技术对比确实有些不公平。但这里讨论的不是公平不公平的问题,而是讨论该使用一个成功的技术还是该使用一个失败的技术的问题。

2、在很多错误的SOAP实践中采用XML套XML的方式的原因是,大家都知道SOAP是一个皇帝的新装,但是又因为SOAP的权威性以至于质疑它的人中没有几个人敢说出这个事实,因为直接说出我不能理解SOAP为什么要设计成这个样子,可能会被人说成是傻瓜。于是就采用了真正傻瓜才采用的方式那就是XML套XML,当然大部分采用这种XML套XML的人自己也知道这很愚蠢,但是又怕别人说自己愚蠢,于是把这种做法说成是好的实践,这样就可以误导更多的新人也采用这种傻瓜做法,当大家都成为傻瓜的时候,自己也就显得不那么傻瓜了。当有揭穿皇帝新装的小男孩说出事实的时候,这群傻瓜和生怕被人说成是傻瓜的装傻者就会站出来说,我们都清楚你说的是事实,但是你不应该说出来,你说出来对我们是不公平的,我们早就意识到了这个问题,我们只是不说而已。

3、以前的错误认知和错误实践都已经是过去了,我们确实没有必要跟过去的事情做太多的计较,但既然大家都已经认识到直接使用RPC方式,或者使用http+xml要比用SOAP套XML方便省事,还不让说出来,还不让大家从错误的实践中纠正过来,还说指责以前的错误实践是没有必要的事如何如何,这样就有点死要面子活受罪的意思了。

4、http在10年前跟现在并没有任何改变,之所以人们认为它越来越强大,涉及到的领域越来越多,并不是http本身的改变造成的,而是使用它的人的思维在改变,在它之上构建的其它技术在发展,SOAP只是这众多技术中出现的较早的一种而已,而且它基本上已经被事实宣布是失败的啦。我们要以发展的眼光看待事物,既然现在有更新更好的可以取代SOAP的技术,我们就没有必要抱着这样一个失败的技术等死,更何况是以错误的用法来使用一个失败的技术。

5、没有人说SOAP不能传递简单的值对象,但是就算是传递简单值对象,它也是最差劲的一种。远程调用技术强调的就是简单明了,不但让你从如何传输数据上(TCP、HTTP已经做到了)解放出来,而且让你从如何进行数据表示上解放出来。使用远程调用技术(也许有的远程调用技术做不到,但是在我知道的远程调用技术中Hprose可以做到)以后你的本地程序业务接口跟远程程序业务接口完全一致,程序员不需要维护多套接口,更不需要单独造什么XML片,这样才能真正从不同方式编写的接口维护中将程序员解放出来。到时候已有的XML片也可以完全废弃,当然如果还有傻瓜继续杞人忧天的继续用这些XML片也可以,只不过这是跟用SOAP套XML一样的愚蠢做法,但即使采用这种愚蠢做法,也比采用SOAP套XML这种做法高效的多,甚至比用纯SOAP还要高效。
26 楼 JE帐号 2010-04-06  
andot 写道
JE帐号 写道
以什么方式传数据,是协议的问题.
数据传过来以后,以什么形式给使用者是应用层问题.
两个不在一个层次上的东西,为什么非要混在一起讨论呢?
所谓轻量级,不是说程序员越轻松就越轻量级.很多轻量级的方案,却对实现有着无比严格的要求和侵入.这样的东西,只轻了自己,一点也没在开放性上考虑.
传xml,你觉得序列化麻烦.那干嘛不用RMI?那还能直接操作远程对象呢.
SOAP的好处从来不是说让你可以在调用一个方法后happy的直接使用一个对象,那根本就不是SOAP所考虑的事情.
最后,虽然现在http很强势,但是还是有很多很多老的系统以及行业,在应用层面不是使用http交换数据,在那些领域SOAP仍然适用.


SOAP本身就是传XML的,而且本身是有标准的。

在SOAP之上再传自定义的XML格式,就等于使用标准的XML封装了非标准的XML。既然这里用了非标准的自定义的XML格式,还有什么开放性可言?明明是你自己根本不理解SOAP是干啥的,还说别人不懂SOAP的好处,这简直就是个笑话。

另外,你这里强调很多很多老的系统以及行业,在应用层面不是使用http而是使用SOAP,我就更要笑话你啦。你说是http出现的早还是SOAP出现的早呢?http从出现到现在都已经20年了,从目前最流行的http1.1算起也有10多年的历史了,在这十多年里,http1.1经历了无数的考验,在其上构建的系统远多于在SOAP之上构建的系统。而SOAP从成为标准到现在还不足10年,最新的SOAP1.2标准距今才只有3年的历史,而且SOAP 1.0、1.1、1.2三个标准的兼容性相当差劲,你还指望使用老版本SOAP协议的系统能跟使用新版本SOAP协议的系统实现互通,这本身就是一个笑话,更何况还要在这个本来就不能很好互通的协议之上再跑一个自定义的非标准的XML,还说这叫开放性,这就是笑话之上的笑话了。http的互通性远比SOAP要好的多,反正都是要交换自定义XML的话,与其再穿上一层XML的外衣,让标准XML套上非标准XML,真的还不如在http上裸奔非标准XML好。

至于你说的为什么要用SOAP而不用RMI传对象,这个道理大家都知道,因为RMI仅限于Java,而SOAP却不是仅限于Java,这跟你说的是不是传对象没有任何关系。所以你这个例子根本证明不了你自己观点。而且要跨平台传输对象,在7年之前,确实SOAP可能是当时最好的选择,但现在来说SOAP已经不是唯一选择,也不是最好的选择了。向PHPRPC、Hprose等新型的高效的跨语言跨平台的远程对象调用的兴起,已经完全可以代替臃肿繁杂的SOAP。所以不管是新系统建设,还是老旧系统的维护,SOAP都没有任何适用的理由了。


1.每个技术都要放在当时的历史环境看.从历史看ws的发展和http的发展根本就是两条线,所以站在现在去简单的批判ws,还拿现在的http来说事,根本就不是一个平等的对比.
2.单就ws来说,之所以那么多实践要在soap的xml内部再嵌套xml.恰恰说明了大家意识到,传输层越简单越好的道理.协议格式与我的业务数据是隔离的,我的业务数据就是一个xml片,至于你的协议是什么,是那个版本,采用什么方式传输都只是我的协议接口实现的问题.从认知的角度,接触到SOAP,觉得麻烦,然后再看到别人好的实践,然后学习到这种"挂羊头卖狗肉"的做法,这就是我的实际学习过程,我只是说出来而已.
3.站在现在看,SOAP还那么有必要么?确实没必要,如你所说,直接http+xml比他还省事,但这是第三个阶段,是一个理解的过程.如同你用惯了现代操作系统,反过头也没必要指责老的操作系统如何如何.
4.http的历史确实很长,但是像现在这样功能越来越强大,涉及领域越来越多从我个人感觉看却只是这几年了功夫,倘若http 10年前就像现在这般无所不能,SOAP也许根本不会出现.
5.SOAP臃肿繁杂并不代表传输简单值对象就不行,远程对象调用也未必真会成主流.如同html一样,传输层越简单越明了越好.这点恐怕很难改变,修改的只是我们使用的具体协议.至于业务的xml片,从未改变过.


25 楼 hatedance 2010-04-06  
我请问lz,你喜欢哪个?
login(String userId,String password);


String xml ="<request><parameter name="userId">foo</parameter><parameter name="password">bar</parameter></request>";
login(String xml);
24 楼 andot 2010-04-06  
gigi_112 写道
做了好几次webservice的接口,总觉得传输xml比传输序列化的对象来的方便,来的直接。
1.对于记录日志,xml更方便,更易读。
2.对于扩展性,xml更加灵活。
3.对于开发过程中的未知因素,显然xml更容易。
4.对于跨语言的需求,显而易见xml才容易实现。


1、格式清晰的纯文本比XML更易读。而对象转换为清晰格式的纯文本要比先解析XML到对象再转换为格式清晰的纯文本高效的多。
2、直接操作对象的扩展性比操作XML的扩展性要方便灵活的多。
3、对于开发过程中的未知因素,没有任何技术可以让你更容易,xml也不能。如果非要说xml能,那么其它其它技术可以比xml能做的更好。
4、对于跨语言的需求,xml是最麻烦的一种实现。目前很多跨语言跨平台的高效通讯协议,比如PHPRPC、Hprose都比XML来的容易,来的高效。
23 楼 andot 2010-04-06  
JE帐号 写道
以什么方式传数据,是协议的问题.
数据传过来以后,以什么形式给使用者是应用层问题.
两个不在一个层次上的东西,为什么非要混在一起讨论呢?
所谓轻量级,不是说程序员越轻松就越轻量级.很多轻量级的方案,却对实现有着无比严格的要求和侵入.这样的东西,只轻了自己,一点也没在开放性上考虑.
传xml,你觉得序列化麻烦.那干嘛不用RMI?那还能直接操作远程对象呢.
SOAP的好处从来不是说让你可以在调用一个方法后happy的直接使用一个对象,那根本就不是SOAP所考虑的事情.
最后,虽然现在http很强势,但是还是有很多很多老的系统以及行业,在应用层面不是使用http交换数据,在那些领域SOAP仍然适用.


SOAP本身就是传XML的,而且本身是有标准的。

在SOAP之上再传自定义的XML格式,就等于使用标准的XML封装了非标准的XML。既然这里用了非标准的自定义的XML格式,还有什么开放性可言?明明是你自己根本不理解SOAP是干啥的,还说别人不懂SOAP的好处,这简直就是个笑话。

另外,你这里强调很多很多老的系统以及行业,在应用层面不是使用http而是使用SOAP,我就更要笑话你啦。你说是http出现的早还是SOAP出现的早呢?http从出现到现在都已经20年了,从目前最流行的http1.1算起也有10多年的历史了,在这十多年里,http1.1经历了无数的考验,在其上构建的系统远多于在SOAP之上构建的系统。而SOAP从成为标准到现在还不足10年,最新的SOAP1.2标准距今才只有3年的历史,而且SOAP 1.0、1.1、1.2三个标准的兼容性相当差劲,你还指望使用老版本SOAP协议的系统能跟使用新版本SOAP协议的系统实现互通,这本身就是一个笑话,更何况还要在这个本来就不能很好互通的协议之上再跑一个自定义的非标准的XML,还说这叫开放性,这就是笑话之上的笑话了。http的互通性远比SOAP要好的多,反正都是要交换自定义XML的话,与其再穿上一层XML的外衣,让标准XML套上非标准XML,真的还不如在http上裸奔非标准XML好。

至于你说的为什么要用SOAP而不用RMI传对象,这个道理大家都知道,因为RMI仅限于Java,而SOAP却不是仅限于Java,这跟你说的是不是传对象没有任何关系。所以你这个例子根本证明不了你自己观点。而且要跨平台传输对象,在7年之前,确实SOAP可能是当时最好的选择,但现在来说SOAP已经不是唯一选择,也不是最好的选择了。向PHPRPC、Hprose等新型的高效的跨语言跨平台的远程对象调用的兴起,已经完全可以代替臃肿繁杂的SOAP。所以不管是新系统建设,还是老旧系统的维护,SOAP都没有任何适用的理由了。
22 楼 gigi_112 2010-04-06  
做了好几次webservice的接口,总觉得传输xml比传输序列化的对象来的方便,来的直接。
1.对于记录日志,xml更方便,更易读。
2.对于扩展性,xml更加灵活。
3.对于开发过程中的未知因素,显然xml更容易。
4.对于跨语言的需求,显而易见xml才容易实现。
21 楼 JE帐号 2010-04-06  
以什么方式传数据,是协议的问题.
数据传过来以后,以什么形式给使用者是应用层问题.
两个不在一个层次上的东西,为什么非要混在一起讨论呢?
所谓轻量级,不是说程序员越轻松就越轻量级.很多轻量级的方案,却对实现有着无比严格的要求和侵入.这样的东西,只轻了自己,一点也没在开放性上考虑.
传xml,你觉得序列化麻烦.那干嘛不用RMI?那还能直接操作远程对象呢.
SOAP的好处从来不是说让你可以在调用一个方法后happy的直接使用一个对象,那根本就不是SOAP所考虑的事情.
最后,虽然现在http很强势,但是还是有很多很多老的系统以及行业,在应用层面不是使用http交换数据,在那些领域SOAP仍然适用.
20 楼 hatedance 2010-04-06  
JE帐号 写道
hatedance 写道
我经常看到有人用了Web Service以后,输入输出参数还是XML的。
为什么啊?
这样还不如直接用http GET/POST好了,WS的好处根本没用到嘛。

1.接口是xml是为了最大限度的保证跨语言性.而不采用文本,又是因为xml的结构性和自解释特点.
2.历史看,http和Web Service也没什么联系.准确的来说,Web Service的祖宗们是为了解决C/S架构下的跨语言调用和通用RPC问题.比如技术,那才叫难使用呢.正因为此,再加上XML当时刚兴起,所以就结合XML出了SOAP.那个时候AJAX的原型-微软的Outlook Web Access才刚开始小范围使用而已,Web技术可还是蛮荒阶段呢,根本不会有人把这两个事情合起来想.
3.SOAP也不限于使用http协议.只是由于现在http协议非常强势,人们习惯性的将二者联系起来.

lz可能误解我的意思了。我的意思是既然用了web service,就应该尽量利用它的好处,比如参数序列化机制。
比如输入输出可以定义为可序列化的类。
如果参数还需要自己再解析,那么你不如直接用http的GET方式,比如GET http://server/foo?xml=abcdef
然后返回一段xml文本即可。
你现在的方案里需要自行序列化/反序列化输入输出参数,做起来应该会比较麻烦的,最好能避免。

这儿我给出一个轻量级的解决方案,可以免去你们的很多工作量。
修改你的doQuery方法签名,返回值为2维数组,我猜想你返回的是结果集。
String[][] doQuery(String queryType, String[] parameters); 

19 楼 JE帐号 2010-04-06  
hatedance 写道
我经常看到有人用了Web Service以后,输入输出参数还是XML的。
为什么啊?
这样还不如直接用http GET/POST好了,WS的好处根本没用到嘛。

1.接口是xml是为了最大限度的保证跨语言性.而不采用文本,又是因为xml的结构性和自解释特点.
2.历史看,http和Web Service也没什么联系.准确的来说,Web Service的祖宗们是为了解决C/S架构下的跨语言调用和通用RPC问题.比如技术,那才叫难使用呢.正因为此,再加上XML当时刚兴起,所以就结合XML出了SOAP.那个时候AJAX的原型-微软的Outlook Web Access才刚开始小范围使用而已,Web技术可还是蛮荒阶段呢,根本不会有人把这两个事情合起来想.
3.SOAP也不限于使用http协议.只是由于现在http协议非常强势,人们习惯性的将二者联系起来.
18 楼 whywen_MoJian 2010-04-03  
顶下lz,偶最近也在做类似的,还没lz搞得更具体。。
17 楼 iooyoo 2010-04-02  
系统就违反了开放-封闭原则 。。。 期望的是日后添加一种新报文后,只在系统中扩展新的请求、查询及响应对象来实现新需求

感觉需求是很简单,设计考虑降低程序的耦合度就可以,楼主说的有点复杂了

当然,用来做例子说明各个原则倒是可以。。。
16 楼 andot 2010-04-02  
hatedance 写道
我经常看到有人用了Web Service以后,输入输出参数还是XML的。
为什么啊?
这样还不如直接用http GET/POST好了,WS的好处根本没用到嘛。


你说对了,Web Service 本来就是皇帝的新装,只是没人愿意(敢)戳穿他罢了。你是个很勇敢的小男孩!我支持你!

相关推荐

Global site tag (gtag.js) - Google Analytics