论坛首页 Java企业应用论坛

Domain Model 探索

浏览 104138 次
该帖已经被评为精华帖
作者 正文
   发表时间:2004-12-29  
Service同Act的差别还是比较明显的。
Service主要实现应用层要求的接口,这当中也有不是业务的方法。比如获得客户信息。
而Act与此不同,他是一个完整的业务,你会产生一个操作员可见的有价值的结果。
0 请登录后投票
   发表时间:2004-12-29  
引用
service 更想一个facade 面向客户,而act是面向业务的


引用

Service主要实现应用层要求的接口,这当中也有不是业务的方法。比如获得客户信息。
而Act与此不同,他是一个完整的业务,


这么看来我的理解还是没有错.但我还是对这个过程化的思维有点耿耿于怀!这和面向对象编程的everything is object的理念有点....郁闷...思考...
0 请登录后投票
   发表时间:2004-12-29  
呵呵,假如你非要看到对象的话,把业务服务层
如:
CustomerService
EmployeeService等
看作对象好了。
这些对象给你提供了相关的服务。
0 请登录后投票
   发表时间:2004-12-29  
frankensteinlin 写道
引用
service 更想一个facade 面向客户,而act是面向业务的


引用

Service主要实现应用层要求的接口,这当中也有不是业务的方法。比如获得客户信息。
而Act与此不同,他是一个完整的业务,


这么看来我的理解还是没有错.但我还是对这个过程化的思维有点耿耿于怀!这和面向对象编程的everything is object的理念有点....郁闷...思考...


service is object,简单的比方,就好像公司里面的客户服务部一样,
客户服务部门通常不是真正为用户提供实际服务的部门,他们是面对用户的接口。

另外,过程化的思维是必然的,面向对象不是抛弃过程,最简单的,use case通常是过程化的。
而且,除了everything is object,也许还可以这样理解,object is everything。就看你怎么看待乐,
在面向对象的分析设计中,最终是会面向过程的(好像有点狡辩的味道)
0 请登录后投票
   发表时间:2004-12-29  
我看了你的设计总觉的有不太对劲的地方,service和operation 分别描述了用户的接口和业务操作,不得不承认,这么做 做到了解耦,而且职责比较清晰。但仍然觉得有 bad smell,where is it?干脆换一种方式思考,从上往下再想一遍。

职责:终于找到问题所在了(有点沾沾自喜,或许想的是错的?),职责过于清晰了,一个operation (act)只有一个方法(public的)从客户的视角来看它就作一件事情(当然实际上它可以做很多)当然职责很清晰:打个比方:flyACT(鸟?飞机?) ,SeeACT(狗?蜜蜂?),EatACT(猪啊);三个ACT都很好的描述了以个行为,职责也很清晰,但是他对问题的描述能力太淡薄了?如果是以个同时具有这三个方法(fly,See,eat)的接口呢?是不是给你的感觉更加清晰一点?回到一个最基本的问题:面向对象的语言和于面向过程的语言优势在哪里?继承? 多态?没错这都是面向对象的特性,要这些特性有什么用呢?回归本质:大大增强了对事物的描述能力!描述能力才是这种新语言的灵魂。(题外话:其实面向过成的思维面向对象的语言并没有舍弃,每个方法的实现还是面向过程的?他是站在了巨人的肩膀上!)

面向过程的语言:fly():函数的定义展现了一个接口,它的实现解决了以个how to fly的问题,面向对象呢?fly():函数的定义展现了一个接口,它的实现解决了以个how to fly的问题。两者没多大区别(多态?只是个副产品,用C写出的编译器她自己不能实现?)但是面向对象能够用能有用一组接口对事物进行描述:(walk,eat,see)你是说一个动物么?(walk,eat,see,think,talk,creative)哇是个人把!

很显然一组接口比一个接口更具有描述能力。

再回头看operation:openAccountACT(Customer:customer)(你使用的是openCustomerACT//我总觉的是开个账户,我对业务不太熟悉,姑且让我按照我的理解说下去,您担待点:-:)暂且不看依赖,不看职责从客户的角度看:我要 开个账户(存钱();取钱();转账();炒外汇())好,我不妨就建立一个 ACCOUNT 的接口有这些个方法 :ACCOUNT{存钱();取钱();转账();炒外汇();开户()}###〔开户这个工作放在一个工厂里面做?〕&(其实开户本省可以调用这个工厂)###问题描述好了:就要开始解决问题了<面向过程的思想开始工作了>

好了开始考虑实现;由于考虑到扩展点.可能对于每一个操作可以建立在相同或者不同的template之上正如你的ACT留个钩子在外面<template模式其实就是面向过程的思维+多态这个特性的产物>。commitment完全可以按照你原来的方式DIP来实现。至于policy我不太理解,如果是一种策略的话完全可以用策略模式来解决 其实策略模式也是一种dip所以你规定的正个依赖结构没有发生变化。

最后看service 我看可以省略了和用户交互的就是IAccount 的接口啊,已经解耦了!为什么还要service?非得把一个人解剖了看,才更清楚? :-)别生气一个比方
0 请登录后投票
   发表时间:2004-12-29  
说老实话,我没看懂你表达的内容。来点code如何?
0 请登录后投票
   发表时间:2004-12-30  
public interface IAccount();{
 public void  openAccoutn();;
 public void diposit();;
...............
}

//后面这部分和你的是相似的.甚至是一莫一样的,只是把一各类变成了一个摸版
public interface OperationTemplate 
{ 
 public doPreprocess();; 
 public doRun();; 
 public doPostprocess();; 
}

// commitment层的接口
public interface CustomerCommitment 
{ 
void affirmCanDo();; 
} 

// 有所简化,其实和原来的一样
//通过依赖倒置实现了commit对operation 的依赖。
//可以由多个模版。(把复杂性隐藏在方法的里面)
//不同的templeate有它的继承体系形成不同的策略,
abstract public class CustomerOperationTemplate /
implements OperationTemplate 
{ 
... 
    public override void doPreprocess(); 
     { 
     ... 
    //扩展点 
    CustomerCommitment customerCommitment = CustomerCommitmentFactory.create(this);; 
    customerCommitment.affirmCanDo();; 
     ... 
    } 
... 
} 



后面的CustomerCommitmentImpl CustomerLostReportAgreementChecker 就不一一列举了,全都可以和你原来是一样的。它其实就是由commitment这个接口有另外一个继承体系衍生。完全独立的一个层次体系。

下面来看Account的一种粗略的实现
SimpleAccount implement IAccount{
   openAccount(Customer customer ); {
     new  CustomerOperationTemplate (); doRun {
	       //Customer customer = Customer.create(...);; <customer这个domainObject是传 入的,它是持久划过了么我不知道>
	       CapitalAccount capitalAccount = CapitalAccount.create(customer,...);; 
	       capitalAccount.deposit(...);; 
	       //OpenCustomerLog.create(this);; <这个可以放到模版里面,是另外一个关注点>
	      save();//持久划。让DAO来决定如何持久化?customer持久化过了么?DAO的object graph会知道的,我不担心。
   }
}


还有两点要说:
1)用template的时候往往可以考虑AOP。像commitment 可以考虑作为一个关注点,当然纯java的解决方案只能template了。

2)我这个方案其实只是将 operation act 移动到对象里面去了,使对象看上去更胖了,似乎承担了更多的职责。其实不然,可以看到它把任务都分包给了不同的对象去处理。怎么分包的被隐藏起来的。当然你的act和service也做到了这样的隐藏。但是注意这里的隐藏是经过分类的。就像嗓子痛:上医院,看看是真的嗓子由问题还是感冒 反正都在医院里。如果 这两个科室在不同的地方客户就会需要考虑自己是嗓子问题还是感冒呢,错了要跑很多冤枉路。同样client再浩如烟海的文档中找寻api也是很痛苦的。

    
0 请登录后投票
   发表时间:2004-12-30  
恩,看得出你是试图合并Service层的服务同业务层的Act。
可以合并吗?
服务层会调用XXXAssembler组装DTO。DTO属于应用层接口的一部分。
假如合并,那么业务逻辑也会依赖应用层接口。
让业务逻辑依赖于应用层接口这是个糟糕的结果。
对于“客户开户”,不同的应用也许会定义出不同的接口。这样
你同样业务逻辑的XXXTemplate的代码会重复出现。
建议你看看MartinFowler关于Service Layer的相关论述。
http://www.martinfowler.com/eaaCatalog/serviceLayer.html
0 请登录后投票
   发表时间:2004-12-30  
引用

When you see a Service Layer (133), a key decision is how much behavior to put in it. The minimal case is to make the Service Layer (133) a facade so that all of the real behavior is in underlying objects and all the Service Layer (133) does is forward calls on the facade to lower-level objects. In that case the Service Layer (133) provides an API that's easier to use because it's typically oriented around use cases. It also makes a convenient point for adding transactional wrappers and security checks


引用

I'm saying not that you should never have service objects that contain business logic, but that you shouldn't necessarily make a fixed layer of them. Procedural service objects can sometimes be a very useful way to factor logic, but I tend to use them as needed rather than as an architectural layer.

My preference is thus to have the thinnest Service Layer (133) you can, if you even need one. My usual approach is to assume that I don't need one and only add it if it seems that the application needs it. However, I know many good designers who always use a Service Layer (133) with a fair bit of logic, so feel free to ignore me on this one. Randy Stafford has had a lot of success with a rich Service Layer (133), which is why I asked him to write the Service Layer (133) pattern for this book


这么看来service就像一个面向客户的facade :是的提供给客户的接口更少,就像一个套装的大礼包.打包销售。提供了一个感念更大的对象。作为client和domain object的一个桥梁。也不错。如仅仅做个代理的话(不过这样的借口不容易稳定)。这么说act/operation 实在是没有存在的必要了
0 请登录后投票
   发表时间:2004-12-30  
唉,老兄,不知道是我没有描述清楚,还是你没理解
都说了Act在于封装业务活动,属于业务层的控制类。
它是独立于具体应用层而存在的。它执行业务的行为怎么可以
放到实现应用层接口的服务层中呢?
再不明白,真的是服了you。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics