锁定老帖子 主题:再次小结领域模型的种种观点
该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间:2005-12-23
引用 能否举个例子介绍一下,如何避开“围绕分类展开的设计”并且能得到OO的好处?
围绕分类法的就是传统的依赖类继承的OO啊。 在这个面向接口的时代,早就是围绕角色而不是分类了。 大家不都说接口就是需求吗?谁还关心分类呀? 还有俺鼓吹的co,根本就是妄图用上帝的设计方法构造世界,早就不鸟什么“分类”了。 |
|
返回顶楼 | |
发表时间:2005-12-23
完美分类是不存在的,完美的原子类型确实存在,但完美分类仅存在于人类的想象当中,换个说法可以称为“主观认识”,这种认识通常被视为建基于片面、孤立、不完整的认识之上。
当然,这并不是说分类法是错误的,事实上,分类法可以说是科学研究的主要手段之一。“第一种是‘屠夫式’,大部分科学家都是这种方式。他们把世界割裂成极小的部分进行分析研究。研究生物的并不研究全部生物,有的只研究动物;研究动物的也不研究全部动物,有的只研究哺乳动物;研究哺乳动物的,有的只研究猴子;研究猴子的有的只研究猴子的尾巴。他们眼中只见树木,不见森林,是极其片面的观点。” 先来看看元素周期表,上帝的设计是如此的简洁、完美,屈指可数的元素竟然构成了物质世界的一切。人类无法窥探上帝设计的奥妙所在,但这并不能阻止人类根据主观认识去对元素进行分类。科学家们根据元素所展现出来的特性将元素一一归类,主要分为六大类:碱金属、碱土金属、过度元素、主族金属、非金属及稀有金属。这种分类法对于科学研究而言并没有什么不妥,分类法的作用仅仅是从某个层面或角度描述元素的共有特性以深化认识并获得简化模型。 那么OO设计呢?从分类的角度出发,不难得到如下设计:元素,碱金属 : 元素,Li : 碱金属。咋看之下,这个设计好象还过得去,没有什么不妥,然而我们不得不指出,这种设计是本末倒置的做法,Li所表现出来的特性是由Li自身的构成所决定(更低层次的粒子构成),而非由人类定义的主观元素分类所决定。 再来看另外一个例子:动物。从食物特性来分类,可以分为肉食动物和植食动物,得出设计如下:动物,肉食动物 : 动物, 植食动物 : 动物。但是如果从另外一个角度出发,又可以分为脊椎动物及非脊椎动物,得出另外一个设计:动物,脊椎动物 : 动物,非脊椎动物 : 动物。这下问题来了,两种分类法完全正交,肉食动物可以是脊椎动物也可以是非脊椎动物,反之亦然,分类体系完全乱套了。现实世界中的大部分事物都是复合体,从单一层面出发确实可以根据分类法得到相对“完美”的简化模型,然而只要遇到垮层面的问题,分类法的缺陷将暴露无遗。 我们需要的是完美的原子类型,而非完美的分类法,另外要指出一点,即使有了完美的原子类型,也仅仅是获得了良好的基础和开端,上帝的设计已经为我们展示了这一切。 |
|
返回顶楼 | |
发表时间:2005-12-23
最完美的原子类型就是方法(或者函数?),一个方法一个类型,可是,这样不就又回到老样子了么?
|
|
返回顶楼 | |
发表时间:2005-12-23
firebody 写道 ognl是可以很好的用在Swing UI上面的。
Hi Firebody, Could you possible do me a favor and share more detailed information about this ognl on Swing trick with me ? Thanks! |
|
返回顶楼 | |
发表时间:2005-12-23
原来此domain model非彼Domain Model(UP中定义的业务流程中对现实的一种体现)。都称之为领域模型,容易引起混乱。
|
|
返回顶楼 | |
发表时间:2005-12-23
thatway 写道 firebody 写道 ognl是可以很好的用在Swing UI上面的。
Hi Firebody, Could you possible do me a favor and share more detailed information about this ognl on Swing trick with me ? Thanks! 我最近正在把Xwork集成进Swing程序里,其中包括了ognl,现在看起来ongl 对 swing component处理和pojo没什么区别。 |
|
返回顶楼 | |
发表时间:2005-12-27
在robbin举的例子中,贫血模型的代码
public Bid placeBid(User bidder, MonetaryAmount bidAmount, Bid currentMaxBid, Bid currentMinBid); throws BusinessException { // Check highest bid (can also be a different Strategy (pattern);); if (currentMaxBid != null && currentMaxBid.getAmount();.compareTo(bidAmount); > 0); { throw new BusinessException("Bid too low.");; } // Auction is active if ( !state.equals(ItemState.ACTIVE); ); throw new BusinessException("Auction is not active yet.");; // Auction still valid if ( this.getEndDate();.before( new Date(); ); ); throw new BusinessException("Can't place new bid, auction already ended.");; // Create new Bid Bid newBid = new Bid(bidAmount, this, bidder);; // Place bid for this Item this.getBids.add(newBid);; // 请注意这一句,透明的进行了持久化,但是不能在这里调用ItemDao,Item不能对ItemDao产生依赖! return newBid; } 看起来是没有问题的,但是placeBid的逻辑根据实际情况,可能有多种实现。 总不能变化一次,修改一次实体类吧。 所以这个逻辑还是放外边好,放到service里面,可以注入不同的service, 实现逻辑的替换。 |
|
返回顶楼 | |
发表时间:2005-12-30
我的实践中,确实有遇到正交或半正交的分类,比如说(某个特定领域的)系统有n类最终用户,分别从他们的视角出发,可以将诸多DomainObject分为n个类型树,这些类型树之间是正交或半正交的。
我目前的方法是将这n棵类型树,用n棵interface的继承树来表现。然后具体到实现系统的某个DomainObject时,根据他在这n棵类型树中的位置,来实现可能的n个interface。 ajoo 写道 在这个面向接口的时代
我不知道这样做是否是所谓的面向接口? 按用户的视角分类,很明显的一点是能做到概念清晰,不论从分析设计人员还是代码实现人员还是最终用户,都比较容易理解业务模型,以及业务模型到代码的对应,另外的好处是基本上可以使用多态来避免业务逻辑中大量的if else。 但是这样做有几个明显的缺点: 1)单独一棵类型树都不一定是完美(稳定)的,n个类型树的不稳定性相互作用,使得Domain层代码的变数成倍增加。 2)在java这样的实现中,通过interface,没有任何的实现代码被重用,系统中的各个DomainObject中,可能充斥大量相似代码。 3)具体实现时,DomainObject必然依赖DAO,而且可能会引起DomainObject的膨胀(可能依赖更多的类似DAO的对外系统进行访问的辅助类)。 最近正在思考,是否能通过AOP来避免 问题2,同时减少 问题1 对系统的影响(或许我该研究一下《AOSD》)? 另外,对 问题3 我也是一直在寻找解决方案(一有空就到javaeye潜水,偶尔换换气 )。 ajoo 写道 还有俺鼓吹的co,根本就是妄图用上帝的设计方法构造世界,早就不鸟什么“分类”了。
怀着忐忑的心情,学习了ajoo的系列文章,不过有些失望,个人理解CO好像只是用OO的方式将诸如 if else / for 这样的语言设备包裹成了一个个特定的Object,然后用这些小Object编程实现 if else / for 这样的逻辑?这样作除了让大多数程序员感到难以理解外,与直接使用 if else / for 有多大区别呢?困惑。。。这样的CO方式,能否用来做Domain的设计/实现? 或许是我对CO理解有误? |
|
返回顶楼 | |
发表时间:2005-12-30
ajoo 写道 引用 能否举个例子介绍一下,如何避开“围绕分类展开的设计”并且能得到OO的好处?
围绕分类法的就是传统的依赖类继承的OO啊。 在这个面向接口的时代,早就是围绕角色而不是分类了。 大家不都说接口就是需求吗?谁还关心分类呀? 还有俺鼓吹的co,根本就是妄图用上帝的设计方法构造世界,早就不鸟什么“分类”了。 分类是人类知识的组织过程和基石,不分类根本无法沟通。 接口难道不是分类?!接口代表了一类特性。本身就是一种类别。 比如:一个公司的人分男人和女人,然后我说会拉小提琴的站到我身后来,于是,公司分为两类人:会拉小提琴的和不会拉小提琴的。 这里会拉小提琴的相当于一个接口: public interface Violin{ void play();; } age0 写道 完美的分类是不存在的,完美的原子类型确实存在 我怀疑完美的原子粒子是否存在。既然你认为它存在那么你总是有考核手段的,你如何证明你的考核手段是正确的。
每一次项目的迭代,以及我们在这里的讨论,只是让我们跟进一步的接近这个真实世界。 回到Domain和Service里, 无论如何,在转帐的例子中,一个account是不需要知道另一个account的存在的。分离关注点下: 转帐是可以被分为一个account减法和另一个account的加法的。 我以为Service存在的意义在于: 1.我们总有些活动是跨domain的(两个含义:同类domain和异类domain的)。 2.表现层使用的是DTO或者VO,相当于英语。而Domain相当于中文,总是需要翻译工作的。 至于serive本身如何再分离关注点,像前面讨论的办户口!应该是另一个话题! |
|
返回顶楼 | |
发表时间:2005-12-30
另外: 我认为Domain是个细粒度的,高内聚低耦合的对象,提供的功能有限,也相对稳定。
而Service不同,service是面向use case的。是相对不稳定的。 当我们要使用AOP来组织业务时(将来某个时候,大家认可后),我们是在service层组织的,这里提供了上下位环境。 所以哪怕在一些方法中只是简单delegate,我认为也是值得的。 |
|
返回顶楼 | |