您的位置:首页 > 编程语言

面向对象之类的设计_代码大全笔记(二)

2012-12-12 17:46 260 查看
类的基础是抽象数据类型。抽象数据类型(ADT)是数据和对这些数据操作的集合。此“数据”为泛指,可以是窗体,文件,链表,汽车,飞机,人等。

类还支持继承和多态,因此可以认为,抽象数据类型 + 继承 + 多态 = 类

任何东西首先展示给人的都是外表,类需要一个良好的接口。(这里的接口主要是指类提供的public函数的集合)

1.合理的抽象

类的接口为隐藏具体实现而提供一种抽象,此接口应该提供一组明显相关的操作。--情非得已别让狗拿耗子

1.一致的抽象层

类设计时,把类看成是实现ADT的机制,每个类只实现一个ADT,若某个类实现了多个ADT,则应把这个类重新组织为多个明确的ADT。

如某个类中一半的子程序使用一部分数据,另一半的子程序使用另一部分的数据,此时可能已经把两个类混在一起了,可以考虑分开。

2.理解类所实现的抽象

一些类非常相似,需要仔细理解类的接口,以确定所需要的抽象是哪个。

3.相反操作

开-关;添加-删除;激活-禁用等,设计类时,不要盲目创建相反操作,要认真考虑,是否需要。-做事情不要太顺手

4.抽象性和内聚性

好的抽象通常也有很高的内聚性,如果发现某个类的内聚性很弱,不知道如何修改,可以尝试看看这个类是否表现了一致的抽象。

2.良好的封装

抽象是忽略实现细节来管理复杂度,而封装是阻止看到细节。--非礼勿视

1.尽可能限制成员的可访问性

如果暴露一个子程序不会破坏抽象的一致性,则这么做是可行的,否则隐藏之会更好。

2.不要公开(public)数据成员

公开数据会破坏封装性,限制对抽象的控制能力。

3.避免把私有的实现细节放入类的接口中

(可参考一中的隐藏抽象的实现细节一节的内容)把private段的内容放到类的头文件中还是暴露了部分的实现细节,可以把类的接口和类的实现隔离开来,在类的接口文件中声明一个指向类实现的指针。

4.避免使用友元

一般情况下友元会破坏封装性,有些场合如设计模式中,使用友元是为了管理复杂度。

5.让阅读代码比编写代码更方便

这个说起来容易做起来也容易,难的是一般程序员不屑于做。-这说到心坎上了

6.留意过于紧密的耦合关系(两个类之间关联)

以下是一些指导建议

尽可能限制类和成员的可访问性

避免友元类

将基类数据声明为private而不是protected,以降低派生类和基类的耦合

避免在类中暴露数据成员

3.类的设计和内部实现

包含(有一个的关系)才是面向对象编程的主力技术。-聚合优先于继承

1.万不得已时通过private继承来实现“有一个”的关系

某些情况下根本无法包含一个对象时,可以通过private继承来实现。-private继承实际是实现继承,相当于将基类的public和protected成员以private声明于子类

2.警惕有太多数据成员的类

研究表明,人们能记住的离散项目的个数是7±2。如果一个类有超过7个数据成员,可以考虑是否有必要分解为更小的类。如果数据成员是整形型者字符串这类简单数据类型,可以按7±2上限考虑,若是复杂对象,则按7±2下限考虑。-这个是否有点绝对化了,看到好多类都是超过这个数的,应该要视情况而言吧
 
当决定使用继承(是一个的关系)时,考虑如下

对于每个成员函数,应该对派生类可见吗?应该有默认的实现吗?此默认实现可以被覆盖(override)吗?

对于每个数据成员,应该对派生类可见吗?

1.public继承实现“是一个......”的关系

如果派生类不准备完全遵守基类定义的同一个接口契约,就不应该用继承。
考虑子类是否需要进行向上类型转换,如果不需要,那么继承就不是正确的实现技术。-这个很关键,不需要多态时应考虑聚合

2.遵循Liskov替换原则

3.派生类的成员函数不要与基类中不可覆盖的成员函数重名

如果一个函数在基类中是私有的,派生类就不要创建一个同名的成员函数。

4.公用的接口,数据放到继承树中尽可能高的位置

多高算高?当把子程序移到更高层次会破坏抽象性,就该停手。

5.派生类覆盖某个子程序,其中没做任何操作,这种情况需要注意

6.避免让继承体系过深

7.尽量使用多态,避免大量的类型检查

8.让所有数据都是private,而非protected

当决定使用多重继承之前,应该仔细考虑其他解决方案。

何时使用继承,何时使用包含

多个类共享数据而非行为,应该创建这些类可以包含的共用对象

多个类共享行为而非数据,应该从共同的基类继承,在基类定义共用子程序

多个类同时共享数据和行为,应该从基类继承,并在基类中定义共用的数据和行为

当需要用基类控制接口时,使用继承;当想自己控制接口时,使用包含。

成员函数和数据成员

让类中子程序尽可能少
禁止隐式地产生成员函数和运算符(类似将赋值运算符声明为private的方式)
减少类所调用的不同子程序的数量(扇入扇出概念)
对其他类的子程序的间接调用尽可能少

尽量减小类与类之前相互合作的范围

尽量让下面的数字最小

所实例化的对象种类
在被实例化对象上直接调用的不同子程序数量
调用由其他对象返回的对象的子程序数量

4.创建类的原因

为现实世界中的对象建模

为抽象对象建模(经典的shape不是真实存在的)

降低复杂度(信息隐藏,无需考虑他们了)

隔离复杂度(隔离复杂算法,大型数据等)

隐藏实现细节

限制变动的影响范围

隐藏全局数据

让参数传递更顺畅

建立中心控制点

代码更易于重用

为程序族做计划

把相关操作包装到一起

实现某种特定的重构

5.应该避免的类

避免创建万能类
消除无关紧要的类
避免动词命名的类
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: