水无常态兵无常势-架构何须拘泥于形式?应赵俊同学的疑问

看过赵俊同学的《三层架构,我为什么对你越来越迷茫了》深有所感,遂作此文以和之。

 软件架构有其共性,但是并没有一定之规,只要符合其规律的,我们就可以根据需求灵活的加以改进。所以赵同学何须拘泥于所谓三层而困惑之。分层理论我们应该活学活用,取其精髓去其糟粕,否则生搬硬套,借句佛家的话来说就是着相了。

究其根本,分层的设计,意图就在于对职责的分离,对于界面来说不用确切的知道业务逻辑的细节,在界面上工作的程序员只需要知道User.Login,但是并不需要知道如何login的,Login的细节是界面不关心的。

而完成业务逻辑方面代码的程序员只需要知道在Login方法的参数传进来了用户的用户名密码,那么在页面上用户名密码是如何显示,如何获取,登录失败了如何提示用户,那都不是他所关心的问题,而对于数据访问提供的DAL.GetUser方法是如何根据用户名获取用户的数据,这个也不是这个程序员所关心的,当然他写的代码也不需要关心,他只需要按照业务逻辑的需求办事就行了。

再说做数据访问代码的程序员,他只关心做业务逻辑的程序员需要什么数据,需要什么数据他就提供什么数据。他不需要关心这些数据被拿去做了什么,更不关心这些数据在页面会怎么显示了。

问题1:分层的模式或者说白了就是三层的架构能够减少工作量吗?答案是:不能,在开发的时候分层会增加不少的代码量,但是如果你要一直维护这个项目的话,最好还是要把职责分开,这样子的代码才好维护。

问题2:分层能够避免在增加功能的时候每个层次都去修改代码么?答案是:在根本上,不能。但是如果你的每个层的接口定义得好留下了余量,那么可以减小许多的修改量。

我们继续来说分层。既然说分层,那么我们如何把层分开呢?这里我们要强调一点“分层是一个逻辑上的概念而不是一个物理上的概念” 当然我也并不是说你就不能把它从物理上分开了,这个问题我们在后面再来继续讨论。首先还是说我的观点,我觉得既然是分层,那么还是在逻辑上要有所表示,说到这里我还要强调一点“分层和设计模式没有必然的联系”,所以赵俊同学的疑问:

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

如果每一层设计成了Web Service,哪改怎么设计?怎么传实体层?到最后这么Web Service会不会变的很臃肿,好像看了园子里面很多资料都没有发现Web Service在三层架构中应用的例子,而且我试了一下发现Web Service不能返回工厂模式生成的接口,提示不能序列化接口。

 

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

在层次之间我不建议使用Factory模式,这个模式是一个创建模式,不适合用来定义层次间的接口契约,在这里再次强调一个概念“广义上的接口并不是单单指的Interface,而是操作上的一种契约” ,在一个DLL中的每一个公共类的公共方法都可以称之为“此组件对外提供的接口这点在很多文章里多次强调重复但是很多人对此还是常常是而不见,怪哉。

我们继续来说接口,我们这里有很多的类,一些是业务逻辑相关的,一些是界面相关的,一些是和数据访问相关的,他们之间的关系是,界面的类会调用业务逻辑的类,业务逻辑的类回调用数据访问的类,那么这个时候就会出现下面的情况,看下图的左图:



 

左图看起来关系是相当的混乱,我们通过Facade模式来改进之。在这里我们不再累述Facade模式是什么了,如果不知道请先进入

http://www.jdon.com/designpatterns/designpattern_Facade.htm

 

那么在这里我们就能够回答赵俊同学的疑问了,不管是用WebService,还是Remoting又或WCF。我们不需要他们返回Interface,而是我们将其作为一个Facade的类。在不同的Dll中的时候也可以采用这种方式。至于WebService会不会变得很臃肿?其实我们可以将业务逻辑再次分类,比如Biiling.asmx,UserManage.asmx......因为如果是采用分布式的话有可能WebService还是访问的不是同一台。

 

 

层次之间建议采用WCF,原因嘛,主要是性能 ,关于WCF的性能可以看看这里:http://www.dotnettools.org/Blog/article.asp?id=203

如果不是.NET3.5的话就要看情况了,如果是都部署在内网,那么就还是不要嫌麻烦用Remoting的好。还有就是没有必要生搬硬套。用一个例子来说明。

比如电子商务的网站,诸如浏览商品列表之类的简单逻辑就直接在Web服务器上了,或者绕开逻辑层去直接去访问数据层也无不可。但是诸如订单流转,计费等复杂逻辑就可以单独用专门的服务器来部署,再次说说WCF的好处,WCF继WebService和消息队列的功能于一身,简直太适合做计费了,用WebService的话就要注意事务的问题,所以如果不用WCF,计费还是消息队列比较好。微软的Biztalk也是处理商务逻辑的一把好手,可惜就是太复杂了,不过如果你对Biztalk很熟的话用这个也很爽(不过这玩意儿的价格可不爽,死贵死贵的)。

 

最后说说实体,一般来说我觉得实体用DTO来说明比较确切,说白了也就是一个数据的载体,至于你想怎么设计是和表一一对应还是怎么的就看你的喜好了,还有也就是对数据层的设计。对于这个部分各有各的说法,不过我个人觉得就和数据表一一对应也没什么不好,有利于引入ORM。

又是问题:实体会贯穿每个层次,那么和数据表一一对应的话不是把数据库的细节都暴露到了?回答是,其实我觉得不过是一个数据的载体,数据层读取数据,逻辑层根据数据作处理,表现层展现数据,围绕的核心是数据,那么一一对应还有什么问题呢?这个时候,数据结构也就是一种契约,在层次间传递数据是最适合不过的了,符合标记耦合的原则(不明白何谓标记耦合的请见拙作《谈谈系统中的耦合以及从另一个角度来解释姜同学的疑虑》), 所以不知道写到这里能够解答赵同学的第二个疑问不。

 

 最后的最后来说说需求,变化无端的需求是不存在的,说一说需求的挖掘和分析也是一门很高深的学问,要学会挖掘客户的需求,乃至潜在需求,甚至能够去引导客户,带动客户将需求转移到对自己更有利的地方。这个要靠非常丰富的经验和超强的能力,现在我还不具备,而且正在为此努力,所以也就不妄谈如何如何做。那么现在我们无法去左右用户的需求所以就只能去迎合用户的需求了。在需求上有一个悖论,当商务人员在很想拿下一个单子的时候多半会在成本允许的情况下很轻易的答应客户的要求,哪怕是无理要求。而对于技术人员来说最理想的情况就是客户需求很简单而且不会变动,不过当然这个情况是不可能的。所以就成了一个悖论了。那么敏捷能够解决这个问题么?那么这又是另外一个话题了,如果谁对需求有兴趣,欢迎开贴响应一下。

 

分层,mvc,面向对象,敏捷开发,都是属于不同领域的方法论,真的是软件工程是没有银弹,他们各自解决了各自领域的一些问题,但是就现在看来,能够彻底打垮需求变更这个恶魔的银弹仍未出现。革命尚未成功,我们还要努力啊

 

 

 

 


 


 

posted on 2008-08-15 20:33  亚历山大同志  阅读(4462)  评论(12编辑  收藏  举报

导航