C++代码重构遵循的原则

匿名 (未验证) 提交于 2019-12-02 23:49:02

在学数据结构的时候,我常有这样目标――写出能够最大程度复用的代码(算法正确,封装优秀)。我常想――如何能在短时间内达成“算法正确,封装优秀”这样的目标。经过一段时间的摸索,我的结论是:先用C写出正确的算法,再将它改写成C++ class,最后再考虑改为template。这种方法简单可行,基本实现了 逻辑(算法)设计与接口设计两个步骤的分离。

下面以一个有界队列为例,进行演示。

正确的算法
在考虑如何实现算法时,可以完全不用任何封装(C struct的封装也不用),只要实现最小操作集合就行了,但测试必须要写。
这里就是实现所谓的“环形缓冲”,空出一个用于区分队满和队空。连同测试,代码如下:


#define BUFMAX 10
int buffer[BUFMAX];
int front = 0;
int rear = 0;

bool empty()
{

}

bool full()
{

}

int size()
{

}

void clear()
{


}

void push(int x)
{


}

int pop()
{




}

void show()
{


(运行结果不在此贴出,感兴趣的同学自己运行)
在只考虑算法不考虑接口的情况下,写出这样的代码很容易(相信有点语言功底的都能写得出来)。当然,上面的#define TEST可以不写,用编译选项定义也是可以的。

封装为class
有了这样的基础,封装为C++ class就很容易了(这里直接包裹,实际情形可能有功能类似但参数不同的接口,略作封装即可)。这么简单的成员函数,没有必要分开来了,这里就用一个.h:



class BoundedQueue {






public:








































封装为类之后,测试代码有必要分开来写:
#include "boundedQueue.h"



int main()
{
















}

重构为class template
显然,这样直接封装的有界队列存在问题――元素类型固定(这通常是写成template的理由),缓冲大小固定。对于第一点,可以通过将代码重构为C++的类模板实现;即将元素的类型作为类模板的一个参数。对于第二点,也可以借助模板参数实现(模板除了有类型参数,也可以有值参数)。当然也可以把buffer改为指针,在ctor传入大小,这里不做介绍。代码如下:



template

{




public:















































此时的测试代码:
#include "boundedQueue.hpp"



int main()
{
















}
这里描述的方法(C->OO->template)主要是从代码复用的角度考虑,并非与传统OOP教材上的“先接口后实现”相违背。你可以理解为――如何让《数据结构》教材上的C代码的到最大程度上的复用。(多数《数据》教材采用C代码讲解,当然也有使用其他语言的)
直接使用“先接口,后实现”的方法,并非不行,只是可能要多改很多次代码(尤其是考虑模板的时候T^T,想想都是泪,不能让学弟学妹们掉同样的坑了)。使用本文所述方法的好处就是――可以让逻辑设计与接口设计两个过程解耦。




版权声明:本文为博主原创文章,转载请附上博文链接!

文章来源: https://blog.csdn.net/u012411498/article/details/96835151
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!