문제

나는 종종 테스트 중심의 개발 사람들로부터 기능을 갖는 것이 많은 양의 정보를 암시 적으로 얻는 것이 나쁘다는 것을 듣는다. 이것이 테스트 관점에서 나쁘다는 것을 알 수 있지만 때로는 캡슐화 관점에서 필요하지 않습니까? 다음 질문이 떠 오릅니다.

무작위와 순서가 좋은 셔플 알고리즘을 사용하고 있습니까?

기본적으로 누군가는 C#에서 함수를 만들어 배열을 무작위로 셔플하기를 원했습니다. 몇몇 사람들은 그에게 임의의 숫자 생성기를 매개 변수로 전달해야한다고 말했습니다. 이것은 테스트가 더 쉬워 지더라도 나에게 캡슐화의 심각한 위반처럼 보입니다. 배열 셔플 링 알고리즘이 배열 이외의 다른 상태를 필요로한다는 사실은 발신자가 신경 쓰지 않아도 된 구현 세부 사항을 셔플 링하는 상태가 아닌가? 이 정보를 얻을 수있는 올바른 장소는 스레드-로컬 싱글 톤에서 암시 적으로 일할 수 없습니까?

도움이 되었습니까?

해결책

예, 그게 끊어집니다 캡슐화. 대부분의 소프트웨어 설계 결정과 마찬가지로, 이것은 두 상대 세력 사이의 상충 관계입니다. RNG를 캡슐화하면 단위 테스트를 위해 변경하기가 어렵습니다. 매개 변수로 만들면 사용자가 RNG를 쉽게 변경할 수 있습니다 (잠재적으로 잘못된 것).

개인적인 취향은 테스트를 쉽게 테스트하고 기본 구현 (이 특정 경우 자체 RNG를 생성하는 기본 생성자)과 최종 사용자를위한 좋은 문서를 제공하는 것입니다. 서명에 메소드를 추가합니다

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

그것은 a를 만듭니다 Random 현재 시스템 시간을 씨앗으로 사용하면이 방법의 대부분의 정상적인 사용 사례를 처리합니다. 원래 방법

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

테스트에 사용될 수 있습니다 (통과 Random 알려진 씨앗이있는 물체) 및 사용자가 암호적으로 안전한 RNG가 필요하다고 결정한 드문 경우. 1 파라미터 구현은이 방법을 호출해야합니다.

다른 팁

나는 그것이 캡슐화를 깨지 않는다고 생각하지 않습니다. 배열의 유일한 상태는 데이터 자체이며 "무작위성 소스"는 본질적으로 서비스입니다. 어레이에 자연스럽게 관련 무작위 성분이 있어야하는 이유는 무엇입니까? 왜 그게 싱글 톤이어야합니까? 다른 요구 사항이있는 다른 상황은 어떻습니까? 이유가 있습니다 java.util.Random a SecureRandom 서브 클래스 :) 아마도 셔플의 결과가 많은 노력과 관찰로 예측할 수 있는지 여부는 중요하지 않습니다. 그것은 컨텍스트에 달려 있으며, 셔플 알고리즘이 신경 쓰지 말아야 할 정보입니다.

서비스로 생각하기 시작하면 종속성으로 전달된다는 것이 합리적입니다.

그래요 당신 ~할 수 있었다 스레드-로컬 싱글 톤에서 얻을 수 있습니다 (실제로 다음 며칠 안에 정확히 그에 대해 블로그에 갈 것입니다). 그러나 나는 일반적으로 그것을 코딩 할 것입니다. 방문객 그 결정을 내립니다.

"서비스로서의 무작위성"개념의 한 가지 이점은 반복성을 만듭니다. 실패한 테스트가 있으면 Random 특정 씨앗을 사용하면 항상 동일한 결과를 얻을 수 있으므로 디버깅이 더 쉬워집니다.

물론, 항상 Random 선택 사항 - 발신자가 자체적으로 제공하지 않으면 스레드 로컬 싱글 톤을 기본값으로 사용하십시오.

나는 이것이 캡슐화를 위반한다고 생각하지 않습니다.

당신의 예

RNG를 제공 할 수 있다는 것은 수업의 특징이라고 말합니다. 나는 그것을 요구하지 않는 방법을 분명히 제공하지만, 무작위 화를 복제 할 수있는 것이 유용한 시간을 볼 수 있습니다.

배열 셔플러가 레벨 생성에 RNG를 사용한 게임의 일부라면 어떨까요? 사용자가 레벨을 저장하고 나중에 다시 재생하려면 RNG 시드를 저장하는 것이 더 효율적일 수 있습니다.

일반적인 경우

이와 같은 단일 작업이있는 간단한 클래스는 일반적으로 내면의 작업을 공개하는 것에 대해 걱정할 필요가 없습니다. 그들이 캡슐화하는 것은 해당 논리에 필요한 요소가 아니라 작업의 논리입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top