锁定老帖子 主题:Domain Model 探索
该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间:2004-12-31
仔细的看了,你要表达的是否主要就是:我们在service层写了太多的东西,引入一个Operation实际上就是action来表达业务操作,将service层的代码简化。
如果是这样的话,这些帖子中没有什么新的内容啊 |
|
返回顶楼 | |
发表时间:2005-01-01
呵呵,我们还是拿个实际的例子具体来分析一下吧
引用 比如“取款”事件,是说某个时间,在某个地点,某个帐户的通过A银行的ATM,余额减少了1000元人民币。
从业务建模的角度来说,我认为这是一个比较具体的业务用例。 我建模的时候首先从其中提取出以下对象: 1、帐户。包括客户信息、资金等 2、ATM机。包括所属银行、地点、现金等 3、货币金额。包括币种、数量等 以上是基础对象,然后是针对业务活动的“取款单” 4、取款单。包括帐户、ATM机、货币金额三者的信息。 按照你所提到的依赖原则,“取款单”依赖于前三个对象。 最后是“事件”,发生了不止一个事件。 5、事件。 帐户:根据某个取款单,资金减少 ATM机:根据某个取款单,现金减少 取款单:在某个时间点,取款成功 如果是跨行交易,涉及到的对象会更多一些。 正如你所说的,把一件事情拆到几个类里来分别实现。不过我认为这是一件很正常的事情,该拆则拆。 |
|
返回顶楼 | |
发表时间:2005-01-01
clamp 写道 最后是“事件”,发生了不止一个事件。 5、事件。 帐户:根据某个取款单,资金减少 ATM机:根据某个取款单,现金减少 取款单:在某个时间点,取款成功 如果是跨行交易,涉及到的对象会更多一些。 考虑一下你说提供的三个事件,我如何知道他们 它们是在一个业务发生的? 要将它们关联到一起,必须要提供一个主事件 这就是我Act的持久态的实体。帐户事件,ATM机事件,取款单事件 都需要与该主事件关联。 进而主事件提供发生时间,发生地点及发生业务类别等信息。 而这些信息,是没法放入任何一个你所提供的事件的,帐户会因为多种原因 资金减少。 也许,可以认为你的取款单事件等价与我这里的主事件。然而你的取款单事件对象能包含什么业务逻辑呢?按照你的设计只可能有一些相关的属性,不可能有业务上有意义的方法。 既然这样我实在看不出这比我直接使用取款Act,有什么优势,取款单事件有的, 取款Act完全能够提供,相反取款单事件不能提供取款业务动态的信息。 而且你之所以将取款单事件建模成类,无外乎是为了得到持久化的Act,难道Act自己就不能持久化? 这就像是事件本事同记者报道出来的新闻一样,还有可能走样。 事件本事就是事件的全部,为什么我还需要看记者的一篇报告稿呢? 将业务活动同持久化的信息都封装在一个类中,而不是再提供一个该对象的持久化“报告”对象。 这样做有什么不好? |
|
返回顶楼 | |
发表时间:2005-01-02
partech 写道 也许,可以认为你的取款单事件等价与我这里的主事件。然而你的取款单事件对象能包含什么业务逻辑呢?按照你的设计只可能有一些相关的属性,不可能有业务上有意义的方法。
恩,取款单事件和你的主事件确实很象。 从业务建模的角度来说,和取款单有关的业务逻辑是从属于取款单对象的。 从设计的角度来说,我通常会引入一个取款单的控制类以对外提供接口。 来看一个比较细节的业务用例:取款单的提交时的逻辑校验,假设包含三个步骤 (1)取款金额是不是合法 (2)帐户中有没有足够的钱 (3)ATM中有没有足够的现金。 在我的设计中,取款单对象只负责第1个步骤,第2个步骤交给帐户对象,第3个步骤交给ATM对象。 虽然是一个过程中的业务逻辑,但是我认为应该把它分解到三个不同的对象中来实现。 而我理解你的设计是把所有的逻辑都放到业务活动中来实现,这个是我所不同意的。 partech 写道 将业务活动同持久化的信息都封装在一个类中,而不是再提供一个该对象的持久化“报告”对象。
这样做有什么不好? 呵呵,没什么不好。不过我觉得这么做违背面向对象的基本概念,更接近于面向过程。 |
|
返回顶楼 | |
发表时间:2005-01-02
clamp 写道 从业务建模的角度来说,和取款单有关的业务逻辑是从属于取款单对象的。
从设计的角度来说,我通常会引入一个取款单的控制类以对外提供接口。 取款Act本身就是一个控制类。 clamp 写道 来看一个比较细节的业务用例:取款单的提交时的逻辑校验,假设包含三个步骤 (1)取款金额是不是合法 (2)帐户中有没有足够的钱 (3)ATM中有没有足够的现金。 在我的设计中,取款单对象只负责第1个步骤,第2个步骤交给帐户对象,第3个步骤交给ATM对象。 虽然是一个过程中的业务逻辑,但是我认为应该把它分解到三个不同的对象中来实现。 而我理解你的设计是把所有的逻辑都放到业务活动中来实现,这个是我所不同意的。 如果你的理解是这样,你就没理解我的设计。 帐户的钱够不够当然只有帐户自己知道; 对于ATM一样。 clamp 写道 partech 写道 将业务活动同持久化的信息都封装在一个类中,而不是再提供一个该对象的持久化“报告”对象。
这样做有什么不好? 呵呵,没什么不好。不过我觉得这么做违背面向对象的基本概念,更接近于面向过程。 违反了什么面向对象的基本概念能否告知? |
|
返回顶楼 | |
发表时间:2005-01-02
这样看起来我们两个并没有什么很大的冲突
你的业务活动Act大致相当于我的取款单控制类, 你的持久化信息大致相当于我的取款单及其相关事件 这样理解不知道是不是正确? 如果是这样,我收回”面向过程“的话。 我们的差别主要还在于看待事物的角度不同。 是先有业务活动,然后有其持久化信息? 还是先有实体对象,然后有对于该实体对象的控制逻辑? 联系你最初提出的”依赖“概念,大致相当于这样一个问题: 是”取款“依赖于”取款单“,还是”取款单“依赖于”取款“ 这个问题我估计只能见仁见智了,呵呵 |
|
返回顶楼 | |
发表时间:2005-01-03
赫赫,差别在于我的控制类Act同时也可以是实体类,如果需要历史记录的话。
而在你的设计中控制类是不能持久化的,如果需要历史纪录,就需要另外创建一个事件类来表达该控制类所进行的业务活动。 如果扯到概念依赖,我想它们本来就是双生的,某个业务活动的发生就意味着某个事件的存在,同时某个事件的存在也意味着曾经发生了某个业务活动。 当然,将两者分别建模也是一种实现的方式,特别是对于只需要记录部分重要业务事件的系统。 不过现在我会选择合并两者,因为在概念上它们本来就是一个东西。 |
|
返回顶楼 | |
发表时间:2005-01-03
恩,基本同意你的看法。
我看我们俩个大致达成一致了,呵呵。 |
|
返回顶楼 | |
发表时间:2005-01-04
引用 是”取款“依赖于”取款单“,还是”取款单“依赖于”取款“ 讨论一个动词和一个名词的依赖关系毫无意义。面向对象的要义是对象决定行为!而不是行为决定对象!”取款“这个行为为什么要依赖取款单?我这个对象实例向我爸这个实例取款就不需要取款单这个对象,取款单 有取款的这个动作与否取决于你是怎样描述取款单的了。有的取款单有,有的没有。 当然你可以规定取款接口,规定继承了取款接口的才能叫取款单,但真正只有一个接口的类是很少的!注意动词作为接口的名字本身有待商榷!取款单 is a 取款? 引用 clamp: 来看一个比较细节的业务用例:取款单的提交时的逻辑校验,假设包含三个步骤 (1)取款金额是不是合法 (2)帐户中有没有足够的钱 (3)ATM中有没有足够的现金。 在我的设计中,取款单对象只负责第1个步骤,第2个步骤交给帐户对象,第3个步骤交给ATM对象。 虽然是一个过程中的业务逻辑,但是我认为应该把它分解到三个不同的对象中来实现。 而我理解你的设计是把所有的逻辑都放到业务活动中来实现,这个是我所不同意的。 我要说的是:上面这个场景的用例的主用例缺失。 引用 当在某个atm机上取款,用户提交取款单(其实是个取款请求) //后面是这个副用例的一种情况 主用例提供了一个对象,这个对象的取款动作发生的时候才会有你们呢个用例(详细描述了取款这个动作的发生[非常具体])的发生。atm这个对象决定了取款的行为。所有的atm取款都是这样的么,不同的atm的取款行为是不同的吧!柜台这个对象取款还是这样的么? 引用 preche 如果你的理解是这样,你就没理解我的设计。 帐户的钱够不够当然只有帐户自己知道; 对于ATM一样。 的确,这方面说你是对的,但是你把这三个步骤封装成一个ACT类是不对的,行为永远在变,执行这个动作的对象不同而已。 |
|
返回顶楼 | |
发表时间:2005-01-04
frankensteinlin 写道 我要说的是:上面这个场景的用例的主用例缺失。 主用例:用户在ATM机上的操作 涉及对象:用户、磁卡、ATM机(假设为本行)、帐户。 (注意:和柜台取款不同,没有明显的取款单实体。) 1、用户将卡插入ATM机、ATM机读卡 2、用户输入密码、帐户验证 3、用户执行操作 1)查询 2)取款 3)退出 这个作为主用例够不够?(可能你的写法和我的写法不同) frankensteinlin 写道 主用例提供了一个对象,这个对象的取款动作发生的时候才会有你们呢个用例(详细描述了取款这个动作的发生[非常具体])的发生。atm这个对象决定了取款的行为。所有的atm取款都是这样的么,不同的atm的取款行为是不同的吧!柜台这个对象取款还是这样的么? 我要指出的是在这个主用例中不存在明显的主要对象。 ATM这个对象(包括其控制类)是不适合作为主对象的,它不应当了解太多的业务逻辑。 这也是我引入“取款单”对象的主要原因。 另外,我认为partech直接将业务活动Act作为对象也是可以的。 |
|
返回顶楼 | |