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


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">##实现随机数库:
</code></pre>

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) );
}

<pre><code class=" line-numbers">##最终程序
我们需要创建3个文件,分别为
```c++
//头文件:random.h

void Randomize();

int GenerateRandomNumber(int low,int high);

double GenerateRandomReal(double low,double high);

```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) );
}

```

测试文件: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;

    return 0;
}

##随机数库的测试
linux 环境下使用g++编译器执行下列命令编译链接生成a.out
```c++
g++ main.cpp random.cpp

<pre><code class=" line-numbers">运行a.out
```c++
./a.out


或者先执行
```c++
g++ -o random main.cpp random.cpp

<pre><code class=" line-numbers">再运行
```c++
./random

###单独测试库的所有函数
合法参数时返回结果是否正确
非法参数返回结果是否正确,即容错功能是否正常

非法参数返回正确:

此处输入图片的描述

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

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

打赏作者