包含(“有一个....”的关系):标志一个类含有一个基本数据元素或对象。
(1)通过包含来实现“有一个/has a”的关系:比如一个雇员“有一个”姓名,“有一个”电话号码。
(2)在万不得已时,通过private继承来实现“有一个”的关系:这么做的主要原因是让外层的包含类能够访问内层被包含类的protected成员函数和数据成员。但是这样会从一定程度上破坏封装性。
(3)警惕又超过约7个数据成员的类:研究表明,人们在做其他事情市能记住的离散项目的个数是7+-2,如果一个类包含超过约7个数据成员,请考虑要不要分解为几个更小的类。如果数据成员都是整形或者字符串这种简单数据类型,你可以按照7+-2的上限来考虑,反之,如果数据成员都是复杂对象的话,就应按7+-2的下限来考虑。
继承(“是一个...”的关系):继承是说一个类是另一个类的一种特化。
(1)用public继承来实现“是一个....”的关系:决定用继承一个现有类的方式创建一个新类事,表明这个新的类是现有类一个更为特殊的版本,基类既对派生类将会做什么设定了预期,也对派生类能怎么运作提出了限制。如果派生类不准备完全遵守由基类定义的同一个接口的契约,继承就是不正确的实现技术了。
(2)要么使用继承并进行详细说明,要么就不要用它。
(3)遵循Liskov替换原则:派生类必须能通过基类的接口而被使用,切使用者无需了解两者之间的差异。换句话说,对于基类中定义的所有子程序,用在它的任何派生类中时的含义都应该是相同的。
(4)确保只继承需要继承的部分:派生类可以继承成员函数的接口和/或实现。
(5)不要“覆盖”一个不可覆盖的成员函数。
(6)把公用的接口、数据及操作放到继承树中尽可能高的位置:如果发现把一个子程序移到更到的层次后会破坏该层对象的抽象性,就停手。
(7)只有一个实例的类是值得怀疑的:Singleton模式是特殊的。
(8)派生后覆盖了某个子程序,担在其中没做任何操作,这种情况也值得怀疑。举例:假设你有一个Cat类,他有一个Scratch(抓)成员函数,可是最终你发现有些猫的爪尖没了,不能抓了,你可能想从Cat类派生一个叫ScratchlessCat(不能抓的猫)的类,然后覆盖Scratch方法让它什么都不做。这种方法是不可取的,修正这一问题的位置不在派生类,而是在最初的Cat类中,应该创建一个Claw(爪子)类并让Cat类包含它,问题的根源在于做了所有猫能抓的假设。
(9)避免让继承体系过深:《Object-Oritented Design Hwuristics》作者Arthur Riel建议把继承层次限制在最多6层之内,Arthur是基于“神奇数字7+-2”这一理论得出这一建议的,但是依经验而言,大多数人在脑中同时应付超过2到3层继承时就有麻烦了,用7+-2来限制一个 基类的派生类总数——而不是继承层次的层数——可能更为合适。
(10)尽量使用多态,避免大量的类型检查:频繁重复出现的case语句有时是在暗示,采用继承可能是种更好的设计选择。
(11)让所有数据都是private(而非protected):如果派生类真的需要访问基类的属性,就应该提供protected访问器函数。
posted on 2007-09-28 09:21
探丫头 阅读(1112)
评论(2) 编辑 收藏 引用 所属分类:
《代码大全》读书笔记