跳转至

ch7 算法纵向拆分,分离表示

1. 迭代器模式

提供一种方法顺序访问一个聚合对象中各个元素,而又不需暴露该对象的内部表示,即与对象的内部表示无关。

  • 不变:产生迭代器的方法不变,迭代器遍历集合的接口不变
  • 变:集合的存储方式可变,迭代器遍历集合的具体实现可变

迭代器模式实现了算法数据表示的隔离。

容器:存储数据,数据的表示

算法:处理数据,抽象的算法实现

迭代器:标准的数据遍历接口,隔离算法与容器,使算法与数据的表示无关

2. 算法与数据的解耦

算法实际上只与 “可用的操作” 相关,与具体的数据类型无关,我们可以抛开类型考虑算法,实现抽象运算,在算法和数据类型(存储)之间实现解耦。

在 C++ 中,可用操作是使用运算符来描述的,它作用在指定数量的操作数上,返回一个结果。我们可以通过运算符重载来实现相关操作,换言之,运算符重载就是在新的数据类型上还原运算符的本质。

可用的操作是数据类型的抽象接口,数据类型也可以用 “可用操作的集合” 来界定,具有相同的 “可用操作的集合” 就是相同的数据类型。如果把 “操作” 更加泛化,将其定义到一个抽象实体上,那么,我们就可以把 “数据类型” 进一步抽象化。

3. 抽象结构与类模板

抽象结构与存储什么数据无关,只与数据的存储方式和访问方式相关,可以借助类模板实现。

泛型编程:先实现算法,再充实数据表示(类型),实现 “算法 / 抽象结构” 与 “数据表示” 之间的分离。

  • 不变:算法 / 抽象结构的接口与实现不变,数据的访问接口不变(迭代器),数据的可用操作不变(运算符重载)
  • 变:数据的组织形式可变,数据的类型(值域、存储、操作实现)可变

内联函数:函数内联展开,避免函数调用开销,用空间换时间。在类定义体内实现的函数默认为内联函数。

4. STL

一组最常用的 C++ 功能的模板实现,包括:

  • 算法:常用算法功能的模板实现
  • 函数对象及其操作:算法的可变部分
  • 容器及其迭代器:算法所所用的一组数据及对其进行遍历的手段