代码改变世界

【讨论】在领域对象里,是否应该存在Setter和Getter?

2011-06-24 20:25  bugfly  阅读(1589)  评论(23编辑  收藏  举报

经过上篇【讨论】“转账功能”引发的“谜团”的讨论,获益良多,首先先感谢各位博友的看法,真是醍醐灌顶,在细品评论的同时,我觉得很有必要结合自身对各位博友评论的理解总结出一些什么来反馈一下,所以特此开多一篇文章来,集思广益。

 

和上篇做法差不多,通过不同做法对比来展开讨论,要注意的是本篇的伪代码完全和上篇没有承接关系,内容上也没有绝对的联系。由于上一篇讨论之前我没有具体说明实现代码实之为伪代码,给部分博友带来不少疑虑,把关注点放到了具体实现上,本人表示十分愧疚!所以在开篇之前先声明:本文说明的代码全是伪代码,大家无需关注具体的实现细节~XD,废话少说,进入正题。

本篇的讨论中心:在领域对象里,是否应该存在Setter和Getter?

为了抛开上一篇说不清的ATM转账用例,这篇拿出来讨论的例子也是非常常见的:“订单管理”,当然这里只不过是简单地展开,没有打算深入研究。

 

既然是订单管理,进一步细化就是:更新订单(Update Order),创建订单(Create Order),查询订单(Retrieve Order),删除订单(Delete Order)了,这是从我的角度展开的,大家不必纠结还有什么,应该是什么。

 

回到订单管理上,细化的功能点想必都是大家再熟悉不过的功能了,等价于CRUD功能吗?或许受数据库技术影响,很多人,包括我也是先入为主,很自然地把这些用例当功能来实现,并没有先从领域对象入手去思考,这些用例中是否存在领域行为,可能这里墨迹的东西比较自我理解化,多都包含!我们先来看第一种实现方法吧。

 

<1>.在Setter和Getter的情况下实现:更新订单,创建订单,查询订单,删除订单

 

可以看到具体的伪代码实现,是多么的熟悉,要注意的是,这里例子使用了DTO,因为考虑到重载爆炸等问题,不喜欢用简单类型作为参数,文章这里不解释DTO是什么了,因为每个人对概念上的东西理解都会不同,我也说不清,也不敢说自己的理解是对的,有兴趣的朋友可以去Virus兄的博客里了解下,我觉得他对DTO见解很不错,但是本文的例子否使用DTO并不影响伪代码的组织实现,大家不必要深究。

 

回过头来,上图代码中Order类的属性都是Public的,每个属性都有对应的Setter和Getter。对于4个功能的实现大家都很熟悉,我也问过很多程序朋友,大部分都颇为仍同这种实现方式,这也是我长期以来的做法,很长一段时间我都不觉得这种做法有什么问题,当然现在为止也是点不出问题所在,所以特意拿出来讨论。

 

结合上一篇评论提到的:Getter/Setter是否提供,是否应该Public 还是Private,还是一个Public一个Private等疑惑,我得出了第二种做法。

 

<2>.在没有Setter和Getter的情况下实现:更新订单,创建订单,查询订单,删除订单

上图做法是站在没有Setter和Getter的前提下实现的,可以看出,代码量较之第一种做法更为简洁,第一种方式中的代码段大部分被嫁接到领域对象中,在这我要强调的是,我并不认为第二种做法是正确的,我也对这种做法持有怀疑态度。

 

结语第二种并不是为了说明要替代第一种做法而实现的,在没有明确讨论结果之前,我不会认同第二种做法是否应该存在替代第一种做法,但从代码量来说,第二种做法确实稍为优胜之。而从CRUD说起,是因为大部分人都惯性从实现功能的角度去分析用例,很少会优先从领域行为入手来分配职责,说这句话,或许只是针对我自己,但并不否定很多人都是这么想的。最后回顾上一篇的AMT转账问题,其实如果从没有Setter和Getter出发,就不会存在第一种情况了,也很自然地出现了第二种情况,而第三种做法依然不知道如何解释。

 

讨论结果:我会总结大家的讨论结果在这里贴出来,请大家保持关注文章结尾这里的讨论结果。我会实时更新。

(*^__^*) ……