边界类,控制类和业务接口的使用,边界类,控制类和业务接口的关系?

问题概述:
思考1:见类图1(http://blog.dreambrook.com//images/blog_dreambrook_com/justin/93/r_1.gif)的情况下,每个边界类(ListForm和DetailForm)分别对应各自的控制类(ListFormController和DetailFormController)每个控制类又都实现了同一个业务接口。该业务接口中分别有A,B,C,D,E,F六个服务(方法),其中A,B,C是为边界类ListForm服务的,而B,C,D是为边界类DetailForm服务的。

思考2:见图2(http://blog.dreambrook.com//images/blog_dreambrook_com/justin/93/r_2.gif)的情况下,每个边界类(ListForm和DetailForm)也分别对应各自的控制类(ListFormController和DetailFormController),但是每个控制类分别实现了不同的业务服务接口,左边的接口中有A,B,C专门为边界类ListForm服务的方法,右边的业务接口有D,E,F专门为边界类DetailForm服务的方法。

思考3:见图3(http://blog.dreambrook.com//images/blog_dreambrook_com/justin/93/r_3.gif)的情况下,每个边界类(ListForm和DetailForm)同时对应一个控制类,该控制类实现了一个业务服务接口。该业务接口中分别有A,B,C,D,E,F六个服务(方法),其中A,B,C是为边界类ListForm服务的,而B,C,D是为边界类DetailForm服务的。

这个问题应该算是个架构设计上的问题吧,
思考1的情况是我现在的做法,但是因为两个控制类实现的是一个总的业务接口,所以每个控制类里都有多余的方法体,一直觉得这样很别扭;
思考2的情况是我的第一个想法,为了保证控制类暴露给边界类的都是有用的方法,所以将总的业务接口拆成了两个业务接口,而两个接口也都是在一个业务服务层中的类来实现的。
思考3的情况是另一个想法,两个边界类共用同一个控制类,后台实现同一个总的业务接口,这也同样给不同的边界类暴露了他们不需要的方法,只是比思考1少用了一个控制类而已。
就这个问题跟同事好一番讨论后,没有一个统一的看法,我自己觉得思考2的实现最好(但是这种方法定义了多个业务接口,这样似乎也不太好!?),其次是思考3,最后才是现在的做法思考1。

也不知道我叙述清楚没有,大家对照类图和我的描述,应该能看懂吧……

我这方面的设计经验还不是很丰富,针对这个问题,各位同仁有什么不同的看法,欢迎大家来一起来讨论讨论。

Justin
MSN:xiaoliang203@hotmail.com

这是一个非常好的讨论题目,可见你对OO设计是有心者。下面是我的讨论,不只理解对否?

首先,我对你提到的三个元素进行我定义的分类:
边界类其实是域模型的界面表现,是一个实体;围绕实体有一个服务类,实际是增删改查的功能类;还有一个控制类:这实际类似一种服务运行实例控制类,我们过去说的工厂类。

如果你认可我这样分类,那么答案就比较直接得出,因为这些正是目前Ioc/AOP框架流行的业务原因。

首先,我们讨论每个边界类是否是需要对应的业务服务接口?
回答是肯定的,这样设计才能达到设计的分离、解耦的目的。业务服务接口多不怕,怕的就是他们都纠缠在一个总接口里,改动起来难免互相影响。

所以你的第2个方案在三个方案中胜出。但是第2个方案还有不到位的地方。

下面是如何解决在运行时刻,如何将边界类和对应的业务服务接口联系起来,而且不用做太多的控制类。控制类实际是一个业务代理实现问题,以前是用工厂模式实现(Jive论坛);后来用Command模式(Petstore中Web对EJB调用);现在是使用Ioc实现,如果你觉得Spring复杂难学,可从我设计的简单小巧的Jdon框架应用开始,它有丰富的中文说明书,比老外的书要容易理解多。

你说的控制类如果用Jdon框架来解决,是ModelHandler实现,这个功能可以用配置解决,只要将业务接口和对应的边界类实现对应指定即可:

<model key="username"
class="com.jdon.framework.samples.jpetstore.domain.Account">
<actionForm name="accountForm"/> //指定边界类
<handler>
<service ref="accountService"> //指定某个业务接口
<getMethod name="getAccount"/>
<createMethod name="insertAccount"/> //业务接口的新增方法
<updateMethod name="updateAccount"/> //业务接口的修改方法
<deleteMethod name="deleteAccount"/>
</service>
</handler>
</model>

上面贴尾部的配置如下:



<class="com.jdon.framework.samples.jpetstore.domain.Account">
<actionForm name=
"accountForm"/> //指定边界类
<handler>
<service ref=
"accountService"> //指定某个业务接口
<getMethod name=
"getAccount"/>
<createMethod name=
"insertAccount"/> //业务接口的新增方法
<updateMethod name=
"updateAccount"/> //业务接口的修改方法
<deleteMethod name=
"deleteAccount"/>
</service>
</handler>
</model>

呵呵,谢谢Bang的回复,让我又学到了很多东西!其实这个问题是我在实际的项目(.Net)中遇到的,虽然不是使用java来实现的,但是我想设计上的思想都应该的共通的。

我也觉得将业务接口拆开比较好,那天因为这个问题跟同事讨论了半天,看法就是不能得到统一,我也不敢说我就是对的,所以就发帖来跟大家讨论了,希望有更多的人能参与进来

其它:我在Jdon注册过用户名为Justin的VIP会员,但是密码怎么也想不起来了,提示问题也忘了,麻烦Bang能不能把我的密码发到我的注册邮箱里~

嘿嘿,永远支持Jdon

你说的是不是就是分层的问题呢?
1、可以把两个控制类的公共方法提出来做一个接口。
2、然后做一个抽象类来实现这个公共接口。
3、每个控制类的特殊方法也做一个接口并实现这个公共接口。
4、最后每个控制类实现自己的特殊方法接口并继承这个抽象类。
common interface
/ | \
controller abstract controller
interface1 controller class interface2
| / \ |
controller controller
class1 class2

优点是:
1、益于维护,对于公共方法只要维护抽象类就可以了。
2、且暴露的接口也是必须的,没有冗余。

不知道是不是这个意思?

yuanfu提出的是一个Adapter模式。将控制类的共用方法和特殊方法最后实现组和适配成最后的要求。是否可这么理解。

我现在想到:如果控制类还做一些流程功能,根据后面业务接口处理的结果,进行不同的页面流程控制,也就是说这里的控制类有Meidator模式在里面。

这种情况应该是一个控制器调用多个接口吧,每个接口的都应该有自己的实现类(不是一个实现类)。控制器调用接口方式很多,IOC/AOP应该是目前比较先进的吧,不过还要看具体情况咯!