`
kuwoleft
  • 浏览: 1077020 次
文章分类
社区版块
存档分类
最新评论

《代码大全》学习笔记二:第六章 可以工作的类

 
阅读更多

第六章,可以工作的类

前言

1、 成为高效程序员的一个关键就在于:当你开发程序任何一部分代码时,都能安全的忽视程序中尽可能多的其余部分。

6.1 类的基础:抽象数据类型(ADTs

抽象数据类型定义

ADT(abstract data type),是指一些数据以及对这些数据所进行的操作的集合。

使用ADT的益处:

1、 可以隐藏实现细节。

2、 改动不会影响到整个程序。

3、 让接口提供更多的信息。

4、 更容易提高性能。

5、 让程序的正确性更显而易见。

6、 让程序更具有自我说明性。

7、 无须在程序内部到处传递数据。

8、 你可以像在显示世界中那样操作实体,而不用在底层实现细节上操作他。

6.2 良好的类接口

创建高质量类的第一步,可能也是最重要的一步:创建一个好的接口。

好的抽象

定义类的时候,把public放在最前面,使用类的时候,一下就可以看到公共的方法。

1、 类的接口应展现一致的抽象层次。每一个类应该实现一个ADT,并且仅实现这个ADT如果你发现一个类不止实现了一个ADT,或者不能确定究竟它实现了何种ADT,你就应该把这个类重新组织为一个或多个定义更加明确的ADT

所谓层次一致,就是要所有的接口都是围绕ADT中的“data”来展开的。并且,要对实现的细节进行隐藏。

2、 一定要理解类实现的抽象是什么。

3、 提供成对的服务。大多数接口都有相应的,相等的,相反的操作。

4、 把不相关的信息转移到其他类中

5、 尽量让接口可编程,而不是表达语义。编程部分有接口中的数据类型和其他属性构成,编译器强制要求他们。语义部分则由“本接口将会怎样被使用”的假定组成,编译器无法强制检查,比如,接口A应该在接口B调用前调用,否则会引起崩溃;调用接口A前需要设置全局变量。等。断言可以将语义部分转换为编程部分?深入研究一下断言。

6、 谨防在修改时破坏接口的抽象。流程编辑中的Node类现在有点杂乱了。

7、 不要添加与接口抽象不一致的公用成员,每次向类中的接口中添加子程序时,问问“这个子程序与现有接口提供的抽象一致吗?”,如果不一致,该如何解决?我遇到过类似的问题,可以参考一下设计模式

8、 同时考虑内聚性和抽象性。

关注类的接口所表现出来的抽象,比关注类的内聚性更有助于深入的理解类的设计。

良好的封装

“设计精良的模块和设计糟糕的模块的唯一最大区别,就是对其他模块隐藏本模块内部数据和其他实现细节的程度。”——Joshua Bloch

封装是比抽象更强的一个概念。抽象通过让你忽略实现细节的模型来管理复杂度,而封装则强制阻止你看到细节。

1、 尽可能限制类和成员的可访问性。让可访问性尽可能的低是促成封装的原则之一。如果无法确定子程序的访问级别(公用,私用,受保护),经验之举是采用最严格且可行的访问级别。更好的建议:采用那种访问级别能够最好的保护接口抽象的完整性?

2、 不要公开暴露成员数据。

3、 避免把私用的实现细节放入类的接口中。不要在private中暴露内部细节(我现在基本都是这样的),一个做法就是可以在private中定义一个指针,指向一个附属类中,附属类中实现了有关的细节。

4、 不要对类的使用做出任何的假设。即尽量让接口可编程,而不是表达语义。

5、 避免使用友元类。State模式中按照正确的方式使用友元类有助于管理复杂度。但一般友元会破坏封装(为什么。查一下。)。他让你在同一时刻考虑更多的代码。

6、 不要因为一个子程序仅使用公用子程序,就把它归入公开接口。

7、 让阅读代码比编写代码更方便。

8、 要格外警惕从语义上破坏封装性。语义上对封装性的破坏很大:它们让调用代码不是依赖于类的公开接口,而是依赖于类的私用实现。每当你发现自己是通过查看类的内部实现来得知该如何使用这个类的时候,你就不是针对接口编程了,而是透过接口针对内部实现编程了。如果你透过接口来编程的话,封装性就被破坏了,而一旦封装性开始遭到破坏,抽象能力也就遭殃了。我的代码中很多地方都是这样使用的。后面要好好的看看。

目前我还找不到办法解决这个问题,有可能是设计的问题。要从根本上解决。

以前对针对接口编程不是很理解。现在终于理解了。

9、 留意过于紧密的耦合关系。建议:1)在基类中把数据声明为private,而不是protect,以降低派生类和基类的耦合关系。避免在公开接口中暴露成员数据。要对从语义上破坏封装性保持警惕。

紧密的耦合性总是发生在抽象不严谨或封装遭到破坏的时候。

6.3 有关设计和实现的问题

这一节主要是关于类内部的设计和实现。

包含(“有一个 ”的关系)

包含表示一个类含有一个基本数据元素或对象,继承比包含复杂的多,不是因为继承比包含更好。包含才是面向对象中的主力技术。

1、 包含表示有一个的关系。

2、 在万不得已是通过private继承来实现有一个的关系。

3、 警惕有超过约7个数据成员的类。如果超过7+ -2个成员,考虑把这个类分解成更小的类。简单数据成员上限9个,复杂对象5个。主要的原理就是分而治之,降低单个复杂度。

继承(“是一个 ”的关系)

使用继承是考虑:

1、 对以每一个成员函数,它应该对派生类可见吗?它应该有默认的实现吗?这一默认实现能被覆盖吗?

2、 对每个成员数据:是否对派生类可见?

更详细的说明:

1、 public继承来实现“是一个 ”的关系。能否用private来实现继承,会有什么效果?三种不同的继承:1public类型继承。表示是一个的关系。2private实现继承,基类中所有的公共接口和公共成员都是派生类中的私有接口。3protect继承,所有的公用成员和方法都将成为派生类的protcet成员。

2、 要么使用继承并进行详细的说明,要么就不使用它。使用继承程序增加复杂度,是一种危险的技术,要尽量少用。就像我的service interface一样,现在有点过于复杂。

3、 遵循替换原则:派生类必须能够通过基类的接口而被使用,且使用者无须了解两者之间的差异。如果程序遵循替换原则,继承就能够成为降低复杂度的一个强大工具,因为它让程序员关注于对象的一般特性而不必担心细节。

4、 确保只继承需要继承的部分:1)抽象且可覆盖——继承接口,不继承实现(纯虚接口)。2)可覆盖——继承接口,默认实现,并且可以覆盖默认实现(虚拟接口)。3)不可覆盖——继承接口,默认实现,但是不可覆盖(一般public接口)。继承接口和继承实现都可以继承。如果只是使用实现,则最好使用包含(类的组合)形式。

5、 不要覆盖一个不可覆盖的成员函数——派生类中的成员函数和基类中不可覆盖函数不要重名。

6、 把公用的接口,数据,操作放到继承树中尽可能高的位置,这样方便派生类的使用。高的标尺:根据抽象性来决定,如果把一个子程序移到更高的层次后会破坏该层对象的抽象性,就要停止了。

7、 只有一个实例的类是值得怀疑的。有可能把对象和类混为一谈了。考虑能否创建新的对象(派生类中的差异通过数据而非定义新的类来表达)。单件模式例外。

8、 只有一个派生类的基类也值得怀疑。我的GNodeData设计不是很合理。考虑是否可以把它在优化一下。这样是在做“提前设计”——试图去预测未来的需要,而又常常没有真正了解为了到底需要什么。为未来变化要做的不是创建几层额外的基类,而是让眼下的工作成功尽可能的清晰,简单,直截了当。不要创建任何并非绝对必要的几层结构。

9、 派生后覆盖了某子程序,当中其中没有进行任何操作,这种情况也值得怀疑。这种情况通常是基类中的设计有问题。破坏接口语义,破坏接口抽象,增加维护难度。

10、 避免继承体系过深。过深的继承体系会导致复杂度的增加,与首要技术使命背道而驰。

11、 尽量使用多态,避免大量的类型检查。要根据不同的情况的。

12、 让所有的数据是private,而非protected。继承会破坏封装。增加基类和派生类间的复杂度。

继承往往会让你和程序员的首要技术使命(管理复杂度)背道而驰。从控制复杂度的角度说,你应该对继承持有非常歧视的态度。

总结:何时可以使用继承,何时使用包含:

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

2、 如果多个类共享行为而非数据,应该使用继承。

3、 如果多个类即共享数据,又共享行为,应该让它们从一个共同的基类继承而来,并在基类中定义共用的数据和子程序。

4、 当你先通过基类控制接口时,使用继承。当你想自己控制接口是,使用包含。

分享到:
评论

相关推荐

    Eclipse插件开发学习笔记-源代码1至24章+使用说明

    光盘提供了本书的所有实例程序的...例如,第6章的代码存储在“X:\chapter06”目录下(X为光盘驱动号)。而且每一章的目录和子目录下面都有一个word或者txt文件,该文件介绍该目录的源代码使用方法,请读者参考该文件。

    《C++20设计模式》学习笔记-第6章适配器模式学习代码

    《C++20设计模式》学习笔记-第6章适配器模式学习代码

    JSP网络编程学习笔记源代码 part2

    第六篇为“Web应用高级专题”,主要讲述Servlet过滤器、JSP异常处理、JSP日志、认证和安全、部署等内容;第七篇为“Web应用开发实例”,围绕一个电子商务网站,从需求分析、架构选取、数据存储、开发、测试及部署等...

    GD32学习笔记第一章:点亮LED灯工程

    包含了第一章所介绍的全部源码

    基于ssm的基于云的学习笔记系统代码 - 基于云的学习笔记系统 - bs - java - ssm - spring -代码

    基于ssm的基于云的学习笔记系统代码 | 基于云的学习笔记系统 | bs | java | ssm | spring | springmvc | mybatis | 代码 | 系统 | 网站 | 毕设 | 项目 1、技术栈:微信小程序,springboot,uniapp,vue,ajax,...

    CISSP学习笔记 CISSP关键知识点总结汇总.zip

    CISSP学习笔记、CISSP关键知识点总结汇总,以网上搜集到的CISSP学习资料为基础,补充修改了关键内容,不保证正确。 第一章 通过原则和策略的安全治理 第二章 人员安全和风险管理概念 第三章 业务连续性计划 第四章 ...

    Oracle 10g 学习笔记

    │ ORACLE学习笔记(二)oracle的逻辑结构 - lvhuiqing的专栏 - CSDN博客.mht.lnk │ ORACLE学习笔记(二)SQLPLUS基础 - lvhuiqing的专栏 - CSDN博客.mht │ ORACLE学习笔记(二)SQLPLUS基础 - lvhuiqing的专栏 - ...

    JSP & Servlet学习笔记(第2版)

    本人资源全部免费,更多资源请查看我的上传资源 ==========================... 著作:《Java JDK 5.0学习笔记》、《Java SE 6技术手册》、《Spring技术手册》等  译作:《Ajax实战手册》、《jQuery实战手册(第2版)》

    Tensorflow2.0:学习笔记代码

    2,前五章代码为本人手码,第六章开始为二进制文件,转换,前五章中的章节文件夹中的代码为原始码,供大家参考 3,第五章中的代码部分API为TensorFlow1.0版本中的代码,请谨慎使用,若要在TensorFlow2.0中使用,需要...

    VMP学习笔记之ESI伪代码生成与加密(六)1

    第六章主题:VMP学习笔记之ESI伪代码生成与加密1、构造ESI指令的基本套路2、ESI伪代码加密(保持一致性,前面对Add系列构造出解密代码,所以这里要反向加

    (完整版)Python基础学习笔记.docx

    (完整版)Python基础学习笔记 (完整版)Python基础学习笔记全文共69页,当前为第1页。(完整版)Python基础学习笔记全文共69页,当前为第1页。Python 基础学习笔记 (完整版)Python基础学习笔记全文共69页,当前为第1页。...

    CSAPP:CSAPP的学习笔记和代码

    CSAPP

    java jdk8 学习笔记

    第一章 1.Java 编程语言刚开始 Oak 橡树 办公室外 已被注册 边喝咖啡边讨论名称 2.动态加载类别文档、字符串池(String Pool)等特性为节省内存而设计 3.jdk java development kit java 开发工具集 java se 平台...

    图像匹配matlab代码-digital_image_process:数字图像处理学习笔记

    数字图像处理学习笔记, 根据以下学习指南进行: 学习用书: 数字图像处理 MATLAB 版 冈萨雷斯著 推荐两本书,一本偏理论, 一本偏代码实战(Matlab), 打包下载地址: 链接: 提取码:nd2a 偏理论: <数字图像处理_第三...

    Java开发详解.zip

    020605_【第6章:面向对象(高级)】_抽象类的基本概念笔记.pdf 020606_【第6章:面向对象(高级)】_接口的基本概念笔记.pdf 020607_【第6章:面向对象(高级)】_对象的多态性笔记.pdf 020608_【第6章:面向对象...

    java学习笔记JDK6课件和课本代码

    第一章到第二十一章课件及代码

    《Python编程从入门到实践》-学习笔记-第二章(变量和简单数据类型)

    第二章 变量和简单数据类型 在本章中,你学习了:如何使用变量;如何创建描述性变量名以及如何消除名称错误和语法错误;字符串是什么,以及如何使用小写、大写和首字母大写方式显示字符串;使用空白来显示整洁的输出...

    css网页布局学习笔记(光盘代码)

    光盘提供了本书的所有实例程序的所有源...例如,第6章的代码存储在“X:\chapter6”目录下(X为光盘驱动号)。其中文件夹Scripts的代码是后面几章的flash动画播放时所需要的文件,读者在运行时按照书中的说明加入即可

    c#学习笔记.txt

    c#学习笔记(1) 51099在线学习网发布 文章来源:网络收集 发布时间:2006-05-25 字体: [大 中 小] 51099在线学习网 http://www.51099.com 1, 结构(struct) 与 类(class) [attributes] [modifiers] struct ...

    machineLearningDeepLearning:李宏毅2021机器学习深度学习笔记PPT作业

    PPT,作业代码,学习笔记,上课代码,tensorflow|pytorch将会上传到github,欢迎Star,请多多鼓励。 如何下载本库内容 下载方式 1 git工具下载 ​ git clone 下载方式 2 网页下载 更新记录 PPT部分 路径:...

Global site tag (gtag.js) - Google Analytics