저는 DDD 전문가라고 생각하지 않지만 솔루션 아키텍트는 가능한 한 모범 사례를 적용하려고합니다. 나는 DDD에서 no (공개) 세터 "스타일"의 장단점에 대해 많은 논의가 있고 나는 논쟁의 양쪽을 볼 수있다. 제 문제는 모든 기술, 지식 및 경험이 풍부한 팀에서 일한다는 것입니다. 즉, 모든 개발자가 "올바른"방식으로 일을한다고 믿을 수 없습니다. 예를 들어, 도메인 객체가 객체의 내부 상태에 대한 변경이 메소드에 의해 수행되지만 공용 속성 설정자를 제공하도록 설계되면 누군가는 메소드를 호출하는 대신 속성을 설정해야합니다. 이 예제를 사용하십시오.
public class MyClass
{
public Boolean IsPublished
{
get { return PublishDate != null; }
}
public DateTime? PublishDate { get; set; }
public void Publish()
{
if (IsPublished)
throw new InvalidOperationException("Already published.");
PublishDate = DateTime.Today;
Raise(new PublishedEvent());
}
}
내 솔루션은 속성 세터를 비공개로 만드는 것인데, 우리가 객체를 수화하는 데 사용하는 ORM은 반사를 사용하여 개인 세터에 액세스 할 수 있기 때문에 가능합니다. 그러나 이것은 단위 테스트를 작성하려고 할 때 문제가됩니다. 예를 들어, 다시 게시 할 수없는 요구 사항을 확인하는 단위 테스트를 작성하려면 개체가 이미 게시되었음을 나타냅니다. 확실히 Publish를 두 번 호출 하여이 작업을 수행 할 수 있지만 테스트는 첫 번째 호출에 대해 Publish가 올바르게 구현되었다고 가정합니다. 약간 냄새가 나는 것 같습니다.
다음 코드를 사용하여 시나리오를 좀 더 실제적으로 만들어 봅시다.
public class Document
{
public Document(String title)
{
if (String.IsNullOrWhiteSpace(title))
throw new ArgumentException("title");
Title = title;
}
public String ApprovedBy { get; private set; }
public DateTime? ApprovedOn { get; private set; }
public Boolean IsApproved { get; private set; }
public Boolean IsPublished { get; private set; }
public String PublishedBy { get; private set; }
public DateTime? PublishedOn { get; private set; }
public String Title { get; private set; }
public void Approve(String by)
{
if (IsApproved)
throw new InvalidOperationException("Already approved.");
ApprovedBy = by;
ApprovedOn = DateTime.Today;
IsApproved = true;
Raise(new ApprovedEvent(Title));
}
public void Publish(String by)
{
if (IsPublished)
throw new InvalidOperationException("Already published.");
if (!IsApproved)
throw new InvalidOperationException("Cannot publish until approved.");
PublishedBy = by;
PublishedOn = DateTime.Today;
IsPublished = true;
Raise(new PublishedEvent(Title));
}
}
다음을 확인하는 단위 테스트를 작성하고 싶습니다.
- 문서가 승인되지 않으면 게시 할 수 없습니다
- 문서를 다시 게시 할 수 없습니다
- 게시되면 PublishedBy 및 PublishedOn 값이 올바르게 설정됩니다
- 게시되면 PublishedEvent가 발생합니다.
세터에 액세스하지 않으면 테스트를 수행하는 데 필요한 상태로 개체를 넣을 수 없습니다. 세터에 대한 액세스 권한을 열면 액세스 방지 목적이 무효화됩니다.
이 문제를 어떻게 해결합니까 (d)?