如何设计优雅、简洁、强壮的库?


beautiful
在学堂在线,看见了清华大学乔林教授讲的一门课《基于Linux 的C++》,讲得非常棒,特地记录了部分笔记。

笔记来源课程:

学堂在线 清华大学 20740084X 基于Linux的C++(2016春)

接口

通过接口使用库:包括制定库的头文件与源文件。
优势:不需要了解库的实现细节,只需了解库的使用方法。

接口设计的一般原则:

用途一致

 接口中所有函数都属于同一类问题

操作简单

 函数调用方便,最大限度隐藏操作细节

功能充足

 满足不同潜在用户的需要

性能稳定

 经过严格测试,不存在程序缺陷

下面以实现随机库为例,说明库的设计与实现。

随机库要实现的功能:

1. 在指定范围内随机生成整数。
2. 在制定范围内随机生成浮点数。

##设计随机库的接口:
“`c++
//随机化函数
void Randomize();

<pre><code class=" line-numbers">“`c++
//指定范围内随机生成整数
int GenerateRandomNumber( int low, int high );

“`c++
在制定范围内随机生成浮点数。
double GenerateRandomReal( double low, double high );

<pre><code class=" line-numbers">## 实现随机数库:
“`c++
void Randomize()
{
srand((int)time(NULL));
}

int GenerateRandomNumber(int low,int high)
{
double _d;
if(low>high) //容错设置
{
cout <<“GenerateRandomNumber:Make sure low<=high.\n”;
exit(1);
}
//做映射,加1.0是因为要强制转换为int,比如3.99强制转换下可能会变3,因此要加1,扩大范围
_d = (double)rand() / ((double)RAND_MAX + 1.0);
return( low + (int)(_d * (high – low +1) ) );
}

double GenerateRandomReal(double low,double high)
{
double _d;
if(low>high)
{
cout << “GenerateRandomReal:Make sure low <= high.\n”;
exit(2);
}
_d = (double)rand() / (double)RAND_MAX;
return( low + _d * (high -low) );
}

##最终程序
我们需要创建3个文件,分别为
“`c++
//头文件:random.h

void Randomize();

int GenerateRandomNumber(int low,int high);

double GenerateRandomReal(double low,double high);

<pre><code class=" line-numbers"><br />“`c++
源文件: random.cpp

#include<iostream>
#include<cstdlib>
#include”random.h”
#include<ctime>

using namespace std;

:void Randomize()
{
srand((int)time(NULL));
}

int GenerateRandomNumber(int low,int high)
{
double _d;
if(low>high)
{
//做映射,加1.0是因为要强制转换为int,比如3.99强制转换下可能会变3,因此要加1,扩大范围
cout <<“GenerateRandomNumber:Make sure low<=high.\n”;
exit(1);
}
_d = (double)rand() / ((double)RAND_MAX + 1.0);
return( low + (int)(_d * (high – low +1) ) );
}

double GenerateRandomReal(double low,double high)
{
double _d;
if(low>high)
{
cout << “GenerateRandomReal:Make sure low <= high.\n”;
exit(2);
}
_d = (double)rand() / (double)RAND_MAX;
return( low + _d * (high -low) );
}

“`c++
测试文件:main.cpp

#include<iostream>
#include"random.h"
using namespace std;

int main()
{
int i;
Randomize();
for( i=0;i<8;i++) // 产生8个指定范围内的随机整数
{
int t = GenerateRandomNumber(10,90);
cout << t <<";";
}
cout << endl;
for(i =0; i<8;i++) // 产生8个指定范围内的随机浮点数
{
double t = GenerateRandomReal(10.0,90.0);
cout << t <<";";
}
cout << endl;

<pre><code>return 0;
</code></pre>

}

<pre><code class=" line-numbers">## 随机数库的测试
linux 环境下使用g++编译器执行下列命令编译链接生成a.out
“`c++
g++ main.cpp random.cpp

运行a.out
“`c++
./a.out

<pre><code class=" line-numbers">—————————————————-
或者先执行
“`c++
g++ -o random main.cpp random.cpp

再运行
c++
./random

单独测试库的所有函数

合法参数时返回结果是否正确
非法参数返回结果是否正确,即容错功能是否正常

非法参数返回正确:

此处输入图片的描述

此处输入图片的描述
###联合测试
多次运行程序,查看生成的数据是否随机
测试整数和浮点数随机数是否均能正常工作
测试正确:
maintest

##改进
Randomize();这条语句放在main()里面是不太好的,用户可能会忘记写了而造成错误,因此一个更好的方法是在GenerateRandomNumber(),和GenerateRandomReal()函数中调用它,这样就防止了用户万一没有添加Randomize()而出错,而且对用户来说也是屏蔽了细节,现在用户只需知道GenerateRandomNumber(),和GenerateRandomReal()函数怎么用就行了。

Author Rewards

Leave a Reply

Your email address will not be published. Required fields are marked *