第六章 可以工作的类
**抽象数据类型(ADT)**是描述类的数据与操作的概念。使用ADT的优点包括:
-
隐藏实现细节与内部数据: 通过ADT,我们可以将类的实现细节和内部数据隐藏起来,使用户只需关注接口而不是具体实现。
-
降低耦合: 使用ADT可以降低类之间的耦合度,改变一个类的一部分不会影响到所有的代码。
-
提高性能: 后期对实现进行优化时,由于隐藏了实现细节,可以更容易地提高性能。
-
避免粗心错误: 隐藏内部数据可以防止直接对其进行操作,从而避免可能的粗心错误。
-
传递更多信息: 接口可以传递更多信息,使得程序更具灵活性。
-
自我说明性和可读性: 使用ADT的程序更具自我说明性和可读性,使得代码更容易理解和维护。
良好的接口抽象应该具备以下特点:
-
展现一致的抽象层次,一个类及其接口对应一个ADT。
-
明确抽象的对象。
-
检查是否需要提供成对的服务,如类 Light 可能要提供开灯与关灯的服务。
-
将不相关的独立部分拆分成独立的类。
-
使接口可编程,避免软关系。
-
在修改类的设计时不破坏类的抽象。
-
同时考虑抽象性与内聚性。
良好的封装需要注意以下几点:
-
在不破坏抽象完整性的前提下,限制内部成员与方法的可访问性。
-
不暴露内部数据,尤其是相关联的数据。
-
不暴露类的内部实现,可以通过使用指针指向具体实现来解决。
-
避免对使用者进行假设,明确方法的前提条件。
-
尽量避免使用友元,因为它可能破坏良好的封装。
-
不要因为一个方法只调用了公共方法就将其定义为公开接口。
-
增强程序的可读性。
-
避免语义上破坏封装,例如要求调用方法 A 之前必须要求方法 B。
-
注意紧密的耦合,尽量减少类之间的合作关系。
在设计与实现中,要注意 "has a" 关系和 "is a" 关系:
-
"has a" 关系尽量用包含实现,万不得已时用继承实现。
-
"is a" 关系使用继承实现,要考虑基类内部数据是否对子类可见,避免过深的继承关系。
-
尽量使用多态而非类型检查。
-
尽量让所有数据都是 private。
对于成员数据与函数,应该尽可能减少,禁止隐式地调用不该调用的方法,减少类调用的不同子程序的数量,以及尽量减少与其他类的合作关系。
在构造函数中,尽可能给所有数据进行初始化,对于实现单例属性的类,应将构造函数定义为私有。优先采用深层复制,以避免浅层复制可能带来的问题。
类的优势包括:
-
为现实对象或抽象对象建模。
-
隐藏细节,隔离复杂度,将可能的改变限制在小范围内。
-
集中对特定操作的控制。
-
代码可重用。
-
实现重构。
需要避免的包括:万能类、无关紧要的类、抽象某个动作而非某个对象的类、抽象某族动作的类。
第七章 高质量的子程序
创建子程序的理由包括:
-
降低复杂度。
-
引入中间的、易懂的抽象。
-
避免代码重复。
-
支持继承。
-
隐藏代码执行顺序。
-
隐藏危险操作,如指针操作。
-
提高可移植性。
-
简化布尔式。
-
方便维护。
-
避免臃肿。
不要因为操作过于简单而不愿意将其写作子程序。将简单的操作写成子程序可以增加代码可读性,便于后续修改和增加该操作。
功能内聚性是理想的内聚性,要求一个子程序完成且仅完成一个操作。不理想的内聚性包括顺序的、通信的、临时的、过程的、逻辑的、巧合的内聚性。为改善这些情况,应将子程序的操作拆分成若干子程序。
子程序的名字应描述其功能,避免含糊不清的动词,确保名字能清晰地表达子程序的目的。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Ollama——大语言模型本地部署的极速利器
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· Windows编程----内核对象竟然如此简单?
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用