本文讲述StanfordL类库中random.h接口的整个设计过程来领会C++接口设计原则。
伪随机数的特点
- 从统计的观点看,该数表现的像一个随机数。
- 事先要预测该数的值应该很困难。
C++标准库中的伪随机数
cstdlib类库提供了一个产生伪随机数的低级函数rand,该函数原型为:
int rand();
rand() 函数无须传入参数,该函数返回一个大于等于0且小于等于常量RAND_MAX的整数,RAND_MAX被定义在cstdlib。
为什么要重新设计一个伪随机数接口
- rand函数本身并不总是返回用户所需要的数值,用户可能需要double类型而非int类型的随机数。
- RAND_MAX的值取决于硬件和软件环境。在大多数系统上,RAND_MAX被定义为整型数的最大值,通常为2147483647,用户可能并不需要这么大范围的随机数。
- cstdlib中的低层次接口会在实现过程中提高程序的复杂性,定义一个高层次的random.h接口可以最大化地隐藏这些复杂的实现过程。
为random接口选择正确的函数集
按照接口设计原则:统一性、简单性、充分性、通用性、稳定性以及编程经验我们猜测用户期望从random.h中获得以下功能:
- 在给定范围内产生一个随机整数
- 在给定范围内产生一个随机实数
- 以给定概率模拟一个随机事件
将上述功能转换为一组函数原型得到random.h中的三个函数原型(randomInteger、randomReal、randomChance)再加上设置随机数种子的函数原型setRandomSeed便构成了一个完整的random接口。
/*
* File: random.h
* -----------------
* This file exports function for generating pseudorandom numbers.
*/
#ifndef _random_h
#define _random_h
/*
* Function: randomInteger
* Usage:int n = randomInteger(low, high);
* ----------------------------------------
* Return a random integer in the range low to high,inclusive
*/
int randomInteger(int low, int high);
/*
* Function: randomReal
* Usage:double d = randomReal(low, high);
* ----------------------------------------
* Return a random real number in the half-open interval [low,high).
* A half-open interval includes the first endpoint but not the second,
* which means that result is always greater than or equal to low but
* strictly less than high.
*/
double randomReal(double low, double high);
/*
* Function: randomChance
* Usage: if (randomChance(p)) ...
* --------------------------------
* Return ture with the probability indicated by p. The argument p must
* be a floating-point number between 0 (never) and 1 (always). For
* example, calling randomChance(.30) return true 30 percent of the time.
*/
bool randomChance(double p);
/*
* Function: setRandomSeed
* Usage: setRandomSeed(seed);
* -----------------------------
* Sets the internal random number seed to the specified value. You can
* use this function to set specific starting point for the pseudorandom
* sequence or to ensure that program behavior is repeatable during the
* debugging phase.
*/
void setRandomSeed