我经常听到在这里从测试驱动开发的人,有一个函数来获取大量的信息隐含是一件坏事。我可以看到是这将是糟糕的,从测试的角度来看,而不是它有时需要从封装的角度?以下问题想到:

是使用随机和排序依据良好的洗牌算法?

基本上,有人想创造在C#的功能,随机混合阵列。有几个人告诉他,随机数发生器应作为一个参数传递英寸这似乎是封装的严重违反对我来说,即使它使测试更加简单。这不是一个数组洗牌算法需要比它的洗牌实现细节的阵列的所有其它任何状态调用者不应该关心这个事实?那不是正确的地方,从一个线程局部单获取这些信息是含蓄,可能?

有帮助吗?

解决方案

是,这并打破封装。与大多数软件的设计决策,这是两个对立势力之间的权衡。如果封装RNG,那么你难以为一个单元测试改变。如果你让那么一个参数,你很容易让用户改变RNG(可能搞错了)。

我个人的偏好是可以很容易地测试,然后提供最终用户的默认实现(即创建自己的RNG默认构造函数,在这种特殊情况下)和良好的文档。添加方法与签名

public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> source)

这产生使用当前系统时间作为它的种子将照顾该方法的大多数正常使用情况下,Random。最初的方法

public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> source, Random rng)

可用于测试(在Random对象传递与已知的种子),并且还在少有的情况下,用户决定他们需要一个加密安全RNG。单参数实现应该调用此方法。

其他提示

我不认为它打破封装。阵列中的唯一的状态是数据本身 - 和“随机源”本质上是一个服务。为什么要数组自然有随机性的相关的源?为什么应该必须是单身?怎么样具有不同需求不同的情况 - 例如,速度与被加密安全随机性?还有就是为什么java.util.RandomSecureRandom子类的理由:)也许不要紧洗牌的结果是否是可预见的了很多的努力和观察 - 或许它。这将取决于具体情况,就是这样的洗牌算法不应该关心的信息。

一旦你开始想到它是一种服务,它是有道理的,它的传过来的依赖。

是的,你的可能的从线程局部单得到它(实际上,我将在博客究竟在接下来的几天),但我想一般它的代码,以便在< EM>主叫的得做出决定。

在“随机性即服务”的一个好处概念是,它使重复性 - 如果你已经有了一个测试失败,你可以通过在特定的种子Random,你却知道永远得到相同结果,这使得调试更加容易。

当然,总是有使Random可选的选项 - 使用线程本地单身作为默认如果主叫方不提供自己的

我不认为这违反了封装。

您实施例

我要说的是能够提供的RNG是类的一个特征。我显然提供了不需要它的方法,但我可以看到时间在那里它可能是能够重复随机有用。

如果阵列洗牌是一个游戏,用于电平产生RNG的一部分。如果用户想要保存的水平和后再次播放时,可能更有效地存储所述RNG种子。

常规案例

这有一个单一的任务,像这样简单的类通常不必担心泄露自己的内部运作。它们封装任务是什么的逻辑,而不是由逻辑所需的元素。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top