一个叫做“人”的基类对象。
在建表时, 也就会产生我上面所说的三种方式的不同差异。 至于三种方式的优劣, 暂时不能逐一展开, 不过Fowler那本书里都有提到; 不过读哪本书时, 可千万别当成什么金科玉律, 肺炎的种类很多, 不是吃茴香都能治的。
闲谈:
不过我们至少可以看出, 我们如何建表, 如何找到合适的模型, 并非是照搬现实生活里存在的概念的; 而是从我们的任务的视角上看过去, 存在哪些概念。 后者的判断, 在于我们关心些什么, 关心的这些内容, 造成了哪些程度上的不同, 有很大不同的时候, 我们需要不同的表达, 没有不同时, 我们就采用统一的表达。 而类设计和表设计, 只是我们表达的体现而已。 那么, 你所面对的问题, 从各方面来看, 需要几种表达方式才能完善呢?
同时, 我们在这时候, 不要过多的去考虑全局到具体, 而是把问题割裂开。 这个事情和谈恋爱正好相反,粘在一起的东西, 扯开比较费劲; 而把东西粘起来, 则相对容易。 这是因为我们人脑同一时间可以理清的东西有限。 所以我们要明确的认识到, 哪些东西可以规划到“男人上男厕所, 女人上女厕所”这样的外部规则, 哪些东西满足“男人和女人不同的特征”。 如果一时不容易分清, 至少我们在信息的量上可以做把握(不过这样把握的方式其实不是实质性的, 随着理解的深入, 就要放弃了), 后者往往涉及到一系列信息, 而前者中“男”“女”仅仅是一个用于填入规则的标志。
当然, 我们设计了一个表, 其中有一个字段存储“男”、“女”, 进行面向对象的设计的时候, 我们照样可以弄出一大堆类, 继承人这个类。 当我们调用, 人.上厕所()时, 就各去各的厕所了。 面向对象一般鼓励以这样的方式, 去给出统一的接口(比如这个例子里“人”)。 其优势在于, 当我们多出其它性别时, 比如“半男半女”、“不男不女”, 那些调用“人.上厕所()”的代码, 全都无需改变。
这里有一个假设, 在于“人”这个接口, 比如具有一些属性, 具有一个“上厕所”的方法, 这个接口是稳定的, 不会改变的。 当我们在进行设计时, 要衡量这个假设是不是成立的。 比如上厕所这个行为, 有可能在未来变化为“上厕所(带手纸)”, “上厕所(没带纸)”, 这样一个接口的变动。 很多面向对象设计只所以问题连连, 就在于做出了时效性太强的假设。
为什么这么说呢?
因为接口是有很大概率会变化的, 其区别仅仅是一个月之内就变, 还是这个系统用了3年才变。接口一旦发生变动, 我们往往就要为当初获得的好处埋单了。
所以如何设计, 有时候不是一个绝对化的问题, 而是一个想办法付出最小代价的问题。对于上厕所, 我们可以统一的把上厕所的具体问题外包出去, 比如针对各种情况可能采取的各种方式, 这样我们就产生一个“上厕所的办法”这样一个外部概念。 我们可以想像, 当一个人脑子里有这个概念的时候(“人”这个类别的对象持有某一“上厕所策略”), 就可以根据判断“我是女的, 我上女厕”、“我没带纸、找张报纸”进行行为, 你可以说这些是这女的想的, 但是你也可以认为这些仅仅是外部规则, 这女的只是按照规则机械的行动而已; 这后一种看法, 实际上使得我们容易在
计算机上设计。
这时候, 我们无需使用继承的体系, 而是采用“人.上厕所(策略)”这样的接口, 那么如果我们所关心的“男”、“女”, 和带纸没带纸一样, 仅仅是上厕所策略用以判断的素材而已; 这样, 我们就不需要男人类