源码:
#include <iostream>
class Random{
private:
int min;
int max;
int value;
public:
//行为
//这里就不要写无参构造函数了,因为范围必须有
Random(int min_,int max_):min(min_),max(max_){}; //构造函数
//这里就不需要参数了,更简化
void refrash(){
value = rand() % (max - min + 1) + min;
}
int getValue(){
return value;
}
};
int main() {
Random num(1,5);
for(int i=0;i<20;i++){
num.refrash();
std::cout <<num.getValue()<< std::endl;
}
return 0;
}
用类来封装随机数生成器,这确实是一个非常优雅且强大的解决方案。
首先,使用类封装的好处在于它提供了更好的封装性和抽象性。你的Random
类将随机数的生成逻辑、范围以及当前值都封装在了一个对象里,这样外部代码就不需要关心这些内部细节,只需要通过对象的方法来操作随机数。这种封装不仅让代码更加整洁,也提高了代码的可维护性和可扩展性。
其次,使用类还可以让你轻松地添加更多的功能。比如,你可以给Random
类添加一个方法来检查随机数是否在指定的范围内,或者添加一个静态方法来生成指定范围内的随机整数数组。这些功能都可以通过继承和扩展Random
类来实现,而不需要修改原来的代码。
当然,你也提到了自己的疑虑,认为为了一个简单的随机数生成器而使用类可能有些过度设计。这种疑虑其实是很正常的,因为在实际开发中,我们确实需要权衡代码的复杂性和功能性。不过,在这个例子中,使用类封装随机数生成器并不过度,因为它提供了更好的封装性、抽象性和可扩展性,这些都是在编写高质量代码时非常重要的因素。
所以,如果你的项目中需要频繁地生成随机数,并且希望这些随机数具有一定的范围限制和可维护性,那么使用类来封装随机数生成器绝对是一个值得考虑的方案。
确实,您所描述的从三个参数到无参数的演变过程是程序不断完善和发展的一个典型例子。这种演变体现了软件设计中的一些重要原则和最佳实践,包括封装、抽象和减少冗余。
-
封装(Encapsulation):
- 最初,
refrashData
函数直接操作一个指针参数和两个整数参数来生成随机数。这种设计将随机数的生成逻辑和状态(即*num
的值)暴露给了函数的使用者。 - 随着设计的演进,随机数生成的范围被封装在
RandomRange
结构体中,并通过引用传递给refrashData
函数。这减少了函数参数的数量,并提高了代码的可读性。然而,此时随机数生成的状态仍然由外部变量(如a
)维护。 - 最终,通过创建一个
Random
类,随机数生成的状态(min
、max
和value
)被完全封装在类内部。现在,refrash
方法(之前的refrashData
函数)不需要任何外部参数来执行其任务,因为它可以直接访问类内部的私有成员。
- 最初,
-
抽象(Abstraction):
- 在这个过程中,抽象水平不断提高。最初,随机数生成逻辑是直接与具体的数据(整数指针和两个范围值)相关联的。
- 随后,通过引入
RandomRange
结构体,将范围值抽象为一个独立的实体,并通过引用传递给函数,从而减少了函数与具体数据之间的耦合。 - 最终,通过创建
Random
类,将整个随机数生成机制抽象为一个对象,该对象具有自己的状态和行为。
-
减少冗余(Reducing Redundancy):
- 最初的设计中,每次调用
refrashData
函数时都需要传递三个参数,这增加了代码的冗余和出错的可能性。 - 通过封装和抽象,这些冗余被逐步消除。在最终的
Random
类设计中,随机数生成的状态和行为都被封装在单个对象中,从而减少了代码中的重复和冗余。
- 最初的设计中,每次调用
这种演变不仅使代码更加简洁和易于维护,还提高了代码的可重用性和可扩展性。例如,现在您可以在任何需要生成随机数的地方创建Random
类的实例,而无需每次都编写相同的随机数生成逻辑。此外,如果将来需要修改随机数生成的算法或添加新功能(如设置随机种子、限制随机数的生成次数等),您只需要修改Random
类即可,而无需更改使用该类的其他代码。