技术开发 频道

实战项目分析

2. 面向接口编程

    其实这跟上一个问题有密切联系。面向接口编程,是“依赖于抽象,而不是实现”的具体手段。不管是模块内部,还是个层次之间,面向接口是消除依赖的基础。

    举一个简单的例子:本系统中业务逻辑层会调用数据存取层的方法,得到一些数据。比如调用一个PartnerAccess类的GetPartner的方法。PartnerAccess是数据存取层的一个具体类,负责Patrner表的所有增删改查操作。而业务逻辑层到处充斥着这样的语法:PartnerAccess partnerac = new PartnerAccess();partnerac.getPartner();

    这就是一个典型的依赖于具体实现的方案。这样的后果是,业务逻辑层知道每一个数据表的数据结构,甚至是无需知道的细节,并且对数据层的每一个方法都了如指掌,到处都在使用。当我们开始修改PartnerAccess的其中一个方法的时候(比如增加一个参数)都要修改业务逻辑层的相关代码,但谁知道那些代码都在哪呢?只好重新编译吧,让编译器告诉我们。

    而面向接口编程可以使我们避免这种问题。我们不再依赖于千千万万个PartnerAccess或者什么别的Access类,而是依赖一个IDataAccess的接口。这样,所有的数据存取都被标准化,我们的调用代码便的更简单,不会依赖任何数据库的结构,甚至不需要知道表的名字,有多少个字段等等。当我们增加一个OrderAccess类时,只需在数据存取层增加一个文件,一个类就好了,而不需要更改业务逻辑层的任何代码。

    记住这个原则吧,它也可以说是面向对象的核心思想。会让你受益匪浅的!

3. 领域模型不清晰

    从上面的图中可以看出来,本系统同时使用了两种领域模型,一种是业务对象(Business Object),一种是强类型DataSet(Strong Type DataSet),并且在每个层次中都使用了。

    举个简单的例子:强类型DataSet被应用到ASP.NET的控件绑定上,用来显示数据。而业务对象被WebService暴露给客户端。

    如果有人看过马丁·福勒的那本《企业架构模式》的话,应该会记得对领域模型的选择上有几种方案。其中业务对象和强类型DataSet都被提到了,并且说明了什么时候适用哪个模型。这里我不多说,感兴趣的朋友可以去看看那本书。

    我想说的是,这里使用了两个模型并存的方案。这样就使得系统的领域模型不清晰,而且存在很多的冗余,例如出现了Partner业务对象和PartnerDS强类型DataSet并存的现象,尽管他们各有各的优缺点,但这样势必会造成领域模型的难于维护和代码可读性差的问题。

    其实,特殊情况下,也可以两个同时使用,但要注意,由于业务对象是属于业务逻辑层的,而强类型DataSet是数据存取层的,所以他们都要在自己的范围内活动,不能被其它的层次存取。

    到这里,有人可能会发现一个矛盾就是:使用单一业务对象的话,则会对数据存取层带来额外的开销,因为数据存取层不能知道业务对象的存在,就需要使用抽象,会带来一些代价。但如果使用单一的强类型DataSet的话,就会对业务逻辑层和展现层保留很多的内部数据细节,也会对系统架构造成一些影响,而且也不利于WebService的传输。

    其实,一个合格的设计师,需要对这两种方案做各自的调整,都为自己所用,但只取他们的优势,而避免他们的劣势多带来的麻烦。

    软件设计,何尝又不是一种取舍的艺术呢!

0
相关文章