是的,这确实打破了封装。与大多数软件设计决策一样,这是两种对立力量之间的权衡。如果您封装了 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)
could be used for testing (pass in a Random
object with a known seed) and also in those rare cases where a user decides they need a cryptographically secure RNG. The one-parameter implementation should call this method.