面向对象之类的设计_代码大全笔记(二)
来源:互联网 发布:mac开机风扇声音很大 编辑:程序博客网 时间:2024/05/21 14:48
类的基础是抽象数据类型。抽象数据类型(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.应该避免的类
- 避免创建万能类
- 消除无关紧要的类
- 避免动词命名的类
- 面向对象之类的设计_代码大全笔记(二)
- 面向对象之子程序的设计及防御编程_代码大全笔记(三)
- 面向对象之数据抽象_代码大全笔记(一)
- 代码大全(5)之面向对象设计
- 【JavaSE笔记】面向对象(二)_继承
- 面向对象的设计原则(二)
- JavaScript个人笔记:面向对象设计二(继承)
- 黑马程序员_面向对象(二)
- 04_面向对象(二)
- 黑马程序员_面向对象(二)
- 【JavaSE笔记】面向对象(一)_面向对象入门
- JavaScript面向对象之类的创建
- JavaScript面向对象之类的继承
- 面向对象之类的封装与调用
- 面向对象之类间的关系
- 面向对象编程之类的继承性
- UE4面向对象之类的继承
- php面向对象之类的创建
- 【phpcms-v9】phpcms-v9中栏目页的静态化生成
- 文章20:NGINX配置文件格式及处理流程
- 最近写出一个bug,关于模块在注册时返回-1
- Mac OS X下搭建Android开发环境(包括SDK和NDK)
- IOS开发之──应用之间调用(1)
- 面向对象之类的设计_代码大全笔记(二)
- 如何快速正确的安装 Ruby, Rails 运行环境 [ 转!很好 ]
- vb做的excel小软件
- YII+DWZ,SESSION超时后采用DWZ的弹窗登陆模式
- 打包
- linux dma cache
- yii如何使用事务,begin,commit,rollback
- 手机布局,界面设计,分辨率,密度相关
- Eclipse设置每行行数