在一个面向对象的农场上有一头面向对象的母牛,母牛产面向对象的牛奶。那么,究竟是应当由面向对象的母牛向面向对象的牛奶发出“uncow yourself”消息,还是应当由面向对象的牛奶向面向对象的母牛发出“unmilk yourself”消息呢?
这听上去有点傻,但是却指出了一个很有意思的问题。在分析时,常常会尽可能的按照现实世界模拟。在设计过程中会把这个真实世界模型按照分布系统功能和避免全能类(顾名思义:无所不能的类)这样的经验原则进行修改。农夫类仅仅是从母牛和牛奶接收消息并把他们再发送到合适的目标(如果农夫类没有其他有用的行为,我们可以把这些新的功能增加到母牛和牛奶类中),这种面向对象的农夫类叫做代理类。
在这个设计的评论中,两个设计者很可能会就究竟是由母牛还是牛奶来发出消息进行长时间的争论。这些争论常常是误解的,因为在系统的逻辑设计中这两个方案常常旗鼓相当,并没有优劣之分。但是,物理设计(也就是对软件和硬件平台的效率问题的考虑)常常会显示出一种解决方案代价高于另一种。如果连物理设计都无法对此作出区分,那么设计者可以通过掷硬币来解决争端。
面向对象设计中控制类和代理类的角色虽然通过使用把实体类(模型)同他们的行为(控制器)分离的技术使迁移(或者是代码复用)变得容易,但是在实践中这会导致数据和行为的人为分离。这一分离应被看作是违背了面向对象泛型的基本原则,明确地说,是违背了数据和行为作为一个概念块双向联系的原则。控制类面临的一些问题也就是面向动作泛型所面临的问题,例如不确定的数据/行为依赖。