封装行为,不只是状态
系统理论中,处理巨大、复杂的系统结构时,包容是最有用的构造之一。软件行业中,包容或封装的价值已深入人心。程序语言的结构,如子程序、函数、模块、类等都支持包容了。
模块和包代表了大尺度的封装,而类、子程序和函数代表了更细粒度的。这些年来,我发现类看起来像是程序员最难正确应用的封装。一个有着3000行代码的主方法的类,或者仅有其原始属性的set和get方法的类,都并不罕见。这些例子说明了实现它们的程序员没有完全理解面向对象的思想,没能成功的应用对象作为模块结构的优点。对于熟悉POJO(Plain Old Java Object)和POCO(Plain Old C# Object or Plain Old CLR Object)的程序来说,这正是回归OO本质的建模范例——对象直白、简单却又不“呆板”。
对象封装了状态和行为,其行为由实际的状态定义。设想一个门对象,它有四种状态:关着,开着,正在关,正在开;提供两种操作:开和关。根据状态,开和关的操作会不一样。这种对象的固有的属性使设计过程在概念上很简单。最终归结为两个简单的任务:分配和委托不同对象的责任,包括对象间的交互协议。
没经验的面向对象的开发人员可能会决定把所有的商业规则装入一个经常引用的对象,比如OrderManager或者OrderService。这些设计中,Order,Customer和Item几乎就只被作为记录类型来对待。所有的逻辑被构建在类外,并由一个巨大的、过程式的方式绑定在一起,并且里面还有很多if-then-else结构。这些方法很容易出问题并且几乎不能维护。理由?封装性被破坏了。
总之,不要打破封装性,使用你的编程语言的力量来维持它。