데이터 지향 인터페이스 프로그래밍


9

코드베이스의 일부는 다음과 같은 스타일로 작성되었습니다.

// IScheduledTask.cs
public interface IScheduledTask
{
    string TaskName { get; set; }
    int TaskPriority { get; set; }
    List<IScheduledTask> Subtasks { get; set; }
    // ... several more properties in this vein
}

// ScheduledTaskImpl.cs
public class ScheduledTaskImpl : IScheduledTask
{
    public string TaskName { get; set; }
    public int TaskPriority { get; set; }
    public List<IScheduledTask> Subtasks { get; set; }
    // ... several more properties in this vein, 
    // perhaps a constructor or two for convenience.
}

즉, 자동 속성으로이를 구현하는 유일한 해당 구현으로 각각 동작이없는 속성 세트 만 지정하는 많은 인터페이스가 있습니다. 이 코드는 상당히 상급자 (나 자신보다 훨씬 많은 사람)에 의해 작성되었으며 합리적인 절차 적 코드 인터페이스 사용과는 별개입니다. 다른 사람 이이 스타일을 만났거나 사용했는지, 인터페이스없이 어디서나 구체적인 DTO를 사용하는 것보다 이점이 있는지 궁금합니다.


1
내가 한 한 가지 이유는 COM 호환성 때문이지만 여기서는 귀하의 이유가 아닌 것 같습니다.
Mike

@Mike Interesting, 나는 COM을 사용한 적이 없으며 여기서 사용되지 않습니다. 이 코드 섹션의 작성자에게 그가 COM을 사용할 계획인지 아니면 다른 것을 사용할 것인지 물을 것입니다.
walpen

내 생각에 그는 비교적 가까운 미래에 그 속성 중 하나 이상을 자동이 아닌 것으로 만들 것으로 예상하고 처음 에이 상용구를 작성하는 것은 나중에 주변에서 시간을 절약하기 위해 얻은 습관입니다. C # 사람이 아니므로 내가 말할 수있는 전부입니다.
Ixrec

6
IMHO 그것은 구현이 아닌 인터페이스에 대한 코드 의 과도한 집착과 오용입니다 . 핵심적인 이야기는 유일한 구현 입니다. 인터페이스의 요점은 다형성이지만 속성 전용 클래스는 단순히 다른 값을 가짐으로써 다형성입니다. 동작 (메소드)을 사용하더라도 단일 구현이 주어지면 아무런 의미가 없습니다. 이 넌센스는 코드 전체에 적용되며 유지 관리를 방해합니다. 왜, 무엇을, 어디에서 묻는 지 너무 많은 시간을 낭비합니다. 왜 그렇게했는지, 내가 보지 못한 디자인은 무엇이며, 다른 구현은 어디에 있습니까?
radarbob

2
선행 의견의 대부분은 조기 추상화의 단일 코드 "코드 냄새"에 적용됩니다. 그러나 여기에 빈혈 도메인 모델 "코드 냄새"가 있습니다. 다음을 참조하십시오 : martinfowler.com/bliki/AnemicDomainModel.html
Erik Eidt

답변:


5

여기 내 두 센트가 있습니다 :

  • 우리는 DTO가 최소한 약간의 행동을하지 않을 것이라고 확신하지 않습니다. 그래서 저에게는 앞으로 행동 할 수도 있고 없을 수도있는 물건들이 있습니다.
  • 많은 단독 구현 클래스를 갖는 한 가지 가능한 원인은 디자인의 부족 것을 볼 실패 예를 들어 ScheduledTask, ScheduledJob, ScheduledEvent, ScheduledInspection, 등, 하나는 분리해야 Schedulable어떤 구현의 스케줄을 인터페이스를 제공합니다.
  • 인터페이스를 먼저 만드는 것은 매우 좋은 방법이며 필요한 정보를 제공합니다. 많은 인터페이스는 전혀 구현하지 않아도 시작됩니다. 그런 다음 누군가가 하나의 구현을 작성하고 그 구현을 가지고 있습니다. 두 번째 요점에서 언급 한 것을 피하면 단독 구현 상태는 일시적입니다. 어떤 인터페이스가 결코 두 번째 구현을 절대로 갖지 않을 것이라는 것을 어떻게 미리 알고 있습니까?
  • 우리가 잘 생각하는 인터페이스를 위해 선택한 이름은 미래에 변경되지 않는 경향이 있으므로 해당 인터페이스에 대한 종속성은 영향을받지 않습니다. 반면에 구체적인 클래스는 예를 들어 그 변경 사항을 구현하는 방식에 중요한 일이라는 구체적인 클래스 때 이름이 변경 될 경향 TaxSheet에 변경 될 수 있습니다 SessionAwareTaxSheet중요한 정밀 검사가되었다하지만 인터페이스가 있기 때문에 ITaxSheet아마 그렇게 쉽게 이름을 바꿀 수 없습니다.

결론 :

  • 우수한 설계 관행은 DTO에도 적용됩니다.
  • DTO는 약간의 행동을 추가 할 수 있습니다.
  • 모든 인터페이스는 하나의 구현으로 시작됩니다.
  • 반면에 하나의 인터페이스-일-클래스 콤보가 너무 많으면 지적해야 할 디자인이 부족할 수 있습니다. 당신의 선입견이 정당화 될 수 있습니다 .

4
나는 당신의 대답을 찬성했지만 두 번째 글 머리 기호는 모든 클래스가 자동으로 해당 인터페이스를 가져야한다는 것을 암시합니다. 두 번째 구현이있을 수있는 오프 기회에 인터페이스를 작성하면 인터페이스가 확산되고 YAGNI가 발생합니다.
Robert Harvey

1

인터페이스를 사용하는 DTO에서 본 특정 문제는 다음을 허용한다는 것입니다.

public interface ISomeDTO { string SomeProperty { get; set; }}

public class SomeDTO : ISomeDTO
{
    public string SomeProperty { get; set; }
    string ISomeDTO.SomeProperty { get { /* different behavior */ } set { SomeProperty = value; } }
}

이 패턴이 중요한 행동을 구현하기 위해 빠르고 더러운 핵으로 적용되는 것을 보았습니다. 이것은 매우 혼란스러운 행동을 할 수있는 코드로 이어집니다.

SomeDTO a = GetSomeDTO();
ISomeDTO ia = a;
Assert.IsTrue(a.SomeProperty == ia.SomeProperty); // assert fails!

이것은 풀거나 리팩토링을 유지하기가 어렵고 혼란 스럽습니다. DTO에 행동을 추가하는 IMO는 단일 책임 원칙을 위반합니다. DTO의 목적은 지속성 프레임 워크에 의해 유지되고 채워질 수있는 형식으로 데이터를 표현하는 것입니다.

DTO는 도메인 모델이 아닙니다. DTO가 빈혈 인 경우 걱정하지 않아도됩니다. 빈혈 도메인 모델에 대한 Martin Fowler의 논의 를 인용 하면 :

또한 도메인 객체에 동작을 넣는 것이 지속성 및 표현 책임과 같은 것에서 도메인 로직을 분리하기 위해 계층화를 사용하는 확실한 접근 방식과 모순되지 않아야한다는 점을 강조 할 가치가 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.