Ask员工类型, 根据类型选择相应的处理逻辑, 这就是以上的方案,可以看出这不是一个好的解决办法. 好的方法是什么呢? 既然我们要根据员工的类型来判断采用何种计算方法, 而员工显然知道自己是何种类型以及自己的工作量, 那么为什么不交给员工自己来算呢?(具体实现的时候就会涉及到多态等等方法, 这不是本文讨论的重点,在此不做详细介绍)那这个时候会计部干什么呢? 计算工资这个活动总要有人发起, 所以会计部现在的工作就是Tell所有的员工, 让大家计算工资,然后把结果汇总.
现在你可以看到Don’t Ask, Tell的影子了吧.
Ask 带来的坏处:
Tell 带来的好处:
上面那个计算工资的例子可以说是被用滥了, 再来看看在其他场合如何运用Don’t Ask, Tell的思想. 集合的遍历操作, 在日常的编程中屡见不鲜. 你是否考虑过它也在一定程度上破坏了Don’t Ask, Tell原则呢? We ask for every element in Collection, then operator on it. Why not just tell the collection to do something. 如果采用ask的办法, 在我们的程序中将不断的出现遍历集合的操作. (重复代码,Bad Smell) 所以我们应该将尽量将集合遍历的操作放在集合内即Refactory away External Loops. 如果你留意了.Net2.0对集合类的最新支持ForEach,你就会发现MS也考虑到了这点.
不过如我在.Net2.0的集合操作 --- What i hope?一文中提到, ForEach似乎考虑的还不是非常完善.
当然事情没有绝对, 有人会问究竟Tell到什么程度呢? 是不是Money还要负责自己的兑换操作? 这就看你把汇率放哪了. 如果汇率也在Money中, 那Money可以提供兑换的功能, 但是可以看出这不是一个好的设计. 汇率或许应该在Bank对象中, 那Money的兑换操作还是放在Bank中比较合适. 这里就涉及到责任分配的问题.
Don’t Ask, Tell可以说是面向对象中一个非常重要的原则, 这里只是对其简单介绍,其实它还隐藏了很多重要的思想, 见Enterprise Test Driven Develop一文.