精华帖 (0) :: 良好帖 (2) :: 新手帖 (3) :: 隐藏帖 (4)
|
|
---|---|
作者 | 正文 |
发表时间:2011-01-13
说和做两回事
|
|
返回顶楼 | |
发表时间:2011-01-14
TonyLian 写道 问:面向对象的设计、开发 与 实际工作中的规范化、流程化、定型化 架构之间的矛盾,如何处理?如何使OOA、OOD实战化,特别是在水平各异的整个团队中普遍展开
答:规范化、流程化、定型化与面向对象的设计、开发没有绝对矛盾。开发规范中文书中都把UML的使用模板化了,反而更利于面向对象的设计、开发。或许面向对象更适合迭代式开发,但是瀑布似的规范化、流程化、定型化一样可以使用面向对象。在团队中,水平最高的架构师做OOA,设立整体的规范模板,次之的做OOD,再次之的做OOP,水平各异的团队要保证高水平对低水平人员的足够的review 问:开发规范文书中所定义的模板化的东西,都是共性的东西,是“放之四海而皆准”的东西,它不可能知道我要做的一个项目的其中一个业务是什么样子的。 也就是说,它仅仅能做到框架结构是OO的。我的问题是,如何才能让业务也OO起来呢?比如,课上例子中办理旅游申请这个业务,把申请单和申请人都作成相应的Class。而到了另外一个页面,比如导游回来后要报销,那么报销的科目可能是一个Class。这时候,没有哪个文书或生成工具可以帮助我们。反而,如果我们按照课程中教授的UML方法去给这些业务建模的话,得到的那些Class,又当如何安放到我们的框架规范当中去呢? 答:业务的OO,要在问题域,也就是业务的现实世界模拟抽象出概念模型来,这个概念模型,也就是有概念类组成的,与现实世界的业务是能够一一映射的,有了这个模型,我们就可以OO下去。 问:一个成型的框架,比如 MVC,比如3层结构,已经规定好了,数据通过POJO保存,业务逻辑在Service中,这样Service也好,数据持久层的DAO也好,都成了贫血对象,在有些架构中它们甚至是单例的。POJO是它们之间调用时的参数或返回值。 于是,从结构来看,3层之间各司其责,互相关联;不同POJO也可能有聚合甚至组合关系,这是OO呀。 但是,从业务角度看,通过参数传递数据,通过函数进行运算,这不就是彻头彻尾的PO吗? 所以,“我们就可以OO下去”,到底该如何去做呢? 答:其实我们做一个业务,没有必要彻头彻尾的OO,业务的概念模型OO了,依照成熟的框架把各层的接口设计的OO了,这样就够了。至于具体到每个层次的某一模块,我完全可以是PO的思维来实现的。关键是现实的业务到概念模型的OO映射,概念模型到设计模型的OO映射。到具体的细节实现,不必纠结的 回答到这里,老师将帖子关闭了,但是,我的疑惑才刚刚说到关键的地方。 我还想继续问:那我们上完课,再遇到一个类似 旅行社OA 的项目,还是没法把课上学到的 建模 理论应用在项目中呀? 我承认,我所指的框架,很大程度上受到了SSH的影响。或者说在SSH里,业务如何OO起来? 我想也就是JE里才能看到更好,更能眼前一亮的答案。 |
|
返回顶楼 | |
发表时间:2011-01-14
你是在怀疑老师,还是怀疑你自己,呵呵
|
|
返回顶楼 | |
发表时间:2011-01-14
感谢各位的讨论,受益匪浅。
尤其是 gdpglc peterwei 两位,虽然昨晚我没能上线,但是今天一早就搬板凳听两位讲课。gdpglc 的那段分别 PO和OO 的代码,其实正是我想问的问题。 让大家见笑了~ |
|
返回顶楼 | |
发表时间:2011-01-14
怎么看怎么像做学术论文似的。。。
|
|
返回顶楼 | |
发表时间:2011-01-14
Spring和DDD是没有必然联系的。 不会DDD,照样拿来spring,分3层进行web开发。 但是如果你学习了DDD,结合spring,也挺好的,就是你所谓的OO,所谓的非贫血。 |
|
返回顶楼 | |
发表时间:2011-01-14
peterwei 写道 gdpglc 写道 没人说一定要用。而且现在大部份人都没用。因为它难用,而且大部份人用的是Spring。
好处坏处看经典吧,我说不出新东西。 你这个例子,好象不明显,而且我也不太理解你的需求。我举个别的吧,比如转帐。 从 A帐户取transferNum到B。 以下代码,只表语意 面向过程的方式: //transaction begin Account a=AccountDao.find...... a.setBalance(a.getBalance-transferNum); AccountDao.save(a); Account b=AccountDao.find...... b.setBalance(b.getBalance+transferNum); AccountDao.save(b); //transaction end 面向对象的方式: Account类提供如下方法: void transferTo(Accout a,transferNum){ this.balance-=transferNum; a.balance+=transferNum; } 然后Service 里这样用: //事务开始 Account a=获得Account Acconnt b=获得Account a.transferTo(b,50); //事务结束 ok,我终于理解你的意思了。说得那么绕。哈哈。你直接说充血,就是在Domain Object里把逻辑操作和数据都封装在一起。但这种做法,我是持反对观点的,也不提倡。 action-->service(什么也不做,只管事务之类)-->domain object(里面有操作和属性)--dao 没有疑问了。这样的缺点我说说: 1.domain object和dao形成了双向依赖,复杂的双向依赖有可能产生很多潜在的问题。 2.你这样做会让大家产生很在的误会,导致整个结构的混乱无序。这个是service呢还是domain object呢? 3、service层必须对所有的domain object的业务逻辑提供相应的事务封装方法,太重复了,看着就不爽。比如你service里肯定还有个和object类似的方法transfer。何必多此一举。直接贫血不就行了,这样pojo还简单些。 我的结论,你何必一定要这种充血oo方式,难道就为了完全的oo?java里贫血不挺好的嘛,大家都这么用。 1,DDD的充血模型就一定会出现domain object和dao的双向依赖?不一定吧。 2,团队对DDD的理解确实会出现一些混淆,但是学习任何技术都是需要付出代价的。 3:service不一定出现和domain object对应的方法吧,可以参考DCI理论中动态织入或者事件的机制吧。 个人观点,java开发中使用spring,想充血确实很难,关键是对象的状态怎么维护和控制。向EJB似的搞个容器?太重了吧。并且面向过程也没有什么错吧,至少这么多项目都是这么做的。 所以针对楼主的疑惑,框架级别还是要OO的,业务分析设计也是需要OO的。复杂的业务场景也是需要OO的。至于Service,pojo,dao,action等等,不要管他是OO还是面向过程。just do it! |
|
返回顶楼 | |
发表时间:2011-01-14
建议还是多看一下领域驱动设计方面的书籍。充分理解一下应用层和领域层的划分,服务、领域对象和值对象的关系。
Spring也不是没有充血模型的,Spring Roo就是充血的。 |
|
返回顶楼 | |
发表时间:2011-01-14
搞这么抽象的东西,代码写出来可维护性强就OK了。
|
|
返回顶楼 | |
发表时间:2011-01-14
leexhwhy 写道 peterwei 写道 gdpglc 写道 没人说一定要用。而且现在大部份人都没用。因为它难用,而且大部份人用的是Spring。
好处坏处看经典吧,我说不出新东西。 你这个例子,好象不明显,而且我也不太理解你的需求。我举个别的吧,比如转帐。 从 A帐户取transferNum到B。 以下代码,只表语意 面向过程的方式: //transaction begin Account a=AccountDao.find...... a.setBalance(a.getBalance-transferNum); AccountDao.save(a); Account b=AccountDao.find...... b.setBalance(b.getBalance+transferNum); AccountDao.save(b); //transaction end 面向对象的方式: Account类提供如下方法: void transferTo(Accout a,transferNum){ this.balance-=transferNum; a.balance+=transferNum; } 然后Service 里这样用: //事务开始 Account a=获得Account Acconnt b=获得Account a.transferTo(b,50); //事务结束 ok,我终于理解你的意思了。说得那么绕。哈哈。你直接说充血,就是在Domain Object里把逻辑操作和数据都封装在一起。但这种做法,我是持反对观点的,也不提倡。 action-->service(什么也不做,只管事务之类)-->domain object(里面有操作和属性)--dao 没有疑问了。这样的缺点我说说: 1.domain object和dao形成了双向依赖,复杂的双向依赖有可能产生很多潜在的问题。 2.你这样做会让大家产生很在的误会,导致整个结构的混乱无序。这个是service呢还是domain object呢? 3、service层必须对所有的domain object的业务逻辑提供相应的事务封装方法,太重复了,看着就不爽。比如你service里肯定还有个和object类似的方法transfer。何必多此一举。直接贫血不就行了,这样pojo还简单些。 我的结论,你何必一定要这种充血oo方式,难道就为了完全的oo?java里贫血不挺好的嘛,大家都这么用。 1,DDD的充血模型就一定会出现domain object和dao的双向依赖?不一定吧。 2,团队对DDD的理解确实会出现一些混淆,但是学习任何技术都是需要付出代价的。 3:service不一定出现和domain object对应的方法吧,可以参考DCI理论中动态织入或者事件的机制吧。 个人观点,java开发中使用spring,想充血确实很难,关键是对象的状态怎么维护和控制。向EJB似的搞个容器?太重了吧。并且面向过程也没有什么错吧,至少这么多项目都是这么做的。 所以针对楼主的疑惑,框架级别还是要OO的,业务分析设计也是需要OO的。复杂的业务场景也是需要OO的。至于Service,pojo,dao,action等等,不要管他是OO还是面向过程。just do it! 这个只是个伪劣的OO吧,就不要往OO上靠了吧. |
|
返回顶楼 | |