도메인 엔티티와 함께 ​​일대일 인터페이스를 사용하는 것이 좋거나 나쁜 연습입니까? 왜요?

StackOverflow https://stackoverflow.com/questions/825919

문제

내가 작업하는 일부 DDD 엔터프라이즈 앱에서 볼 수있는 한 가지는 도메인 엔티티와 동일한 인터페이스를 사용하고 속성 및 기능의 일대일 매핑을 사용하는 것입니다. 실제로 도메인 객체는 항상 일대일 인터페이스를 통해 사용되며 모든 도메인 엔티티에는이 스타일의 일대일 인터페이스가 있습니다.

예를 들어:

도메인 개체 계정 :

public class Account : IAccount
{
     public string Name {get;set;}
     //...some more fields that are also in IAccount
     public decimal Balance {get;set;}
}

그리고 그것은 인터페이스 일치합니다

public interface IAccount
{
   string Name {get;set;}
   //... all the fields in Account
   decimal Balance {get;set;}
}

그러나 최근에 나는 이것이 실제로 반란제라는 것을 점점 더 확신하게되었습니다.
나는 오픈 소스 커뮤니티의 일부 건축가들에 의해 그것을 운영했으며, 이것은 디자인 체인의 어딘가에 디자인 실수 나 결함을 기반으로한다고 말합니다.

그래서 동료들에게 도메인 객체에 대한 인터페이스 생성을 종료해야한다고 말합니다. 그들에게 목적이 없기 때문에 도메인 엔티티를 업데이트 할 때마다 인터페이스를 업데이트해야합니다.

먼저 이러한 인터페이스가 '디커플링'을 제공한다는 주장이 있었지만 인터페이스가 도메인 엔티티와 일대일 관계를 가지고 있기 때문에 실제로 디퍼 커플 링을 제공하지 않기 때문에 인터페이스의 변경은 변경을 의미합니다. 도메인 엔티티 및 그 반대도 마찬가지입니다.

다음 주장은 테스트 목적으로 인터페이스가 필요하다는 것입니다. 내 카운터는 Rhino-Mocks가 콘크리트 클래스의 조롱과 스터브를 제공한다는 것입니다. 그러나 그들은 Rhino-mocks가 구체적인 클래스에 문제가 있다고 주장합니다. Rhino-Mocks가 구체적인 클래스에 어려움을 겪더라도 구매하는지 모르겠습니다. 이것이 반드시 도메인 엔티티에 인터페이스를 사용해야한다는 의미는 아닙니다.

그래서 나는 궁금합니다 :

도메인 엔티티를위한 일대일 인터페이스가있는 이유는 무엇입니까?

왜 안 돼?

왜 좋은 연습입니까?

읽어 주셔서 감사합니다!

편집하다: 나는 항상 인터페이스를 사용한다는 점에 유의해야하며, 그것이 호출되면 모자를 떨어 뜨릴 때 인터페이스를 사용할 것이라고 생각합니다. 그러나 저는 일대일 인터페이스가있는 도메인 엔티티를 구체적으로 언급하고 있습니다.

도움이 되었습니까?

해결책

설명 된대로 나쁜 연습이지만 ...

인터페이스가 도메인 엔티티와 다를 필요가 있다는 구체적인 이유는 없습니다. 때로는 실제로 올바른 매핑입니다. 그러나 그것은 항상 사실이라고 의심 스럽다. 관심의 요점은 인터페이스가 진정으로 설계되었는지 또는 시간 / 게으름이 부족하여 방금 제자리에 던져 졌는지 여부에 대한 의문이 있습니다.

예제를 사용하려면 설명하는 iAccount 인터페이스는 계정 객체에 getters and setter를 노출시킵니다. 계정을 사용하는 모든 것이 계정에서 잔액을 설정해야하며 암시 적 허가가 해당 인터페이스 수준에 지정된 것은 조금 이상하게 보입니다. 시스템에 계정 잔액을 확인하고 설정하지 않는 곳이 없습니까?

다른 팁

클래스로서 직접적으로 도메인 개체를 인터페이스로 항상 지정하는 가장 큰 이유는 구현에서 어느 정도의 자유를 제공하기 때문입니다. 당신의 예에서는 당신은 하나의 iAccount 만 가지고 있으므로 약간의 redunant입니다.

그러나 예를 들어 : 예를 들어

public class Account : IAccount { ... }       // Usual account, persistent
public class MockAccount : IAccount { ... }   // Test mock object
public class TransAccount : IAccount { ... }  // Account, not persistent
public class SimAccount : IAccount { ... }    // Account in a performance sim

등등?

도메인 객체를 인터페이스로 정의하면 도메인 정의를 방해하지 않고 구현을 대체 할 수 있습니다.

일반적으로 수업이 전략이나 방문자와 같은 디자인 패턴의 일부가되지 않으면 인터페이스를 추가하지 않습니다.

인터페이스를 추가하는 것은 전략 및 방문자와 같은 디자인 패턴에 정말 유용하지만,이 경우 도메인 클래스의 게터와 세터를 카본화하지 않습니다. 대신, 내가 만든 디자인 패턴 인터페이스에 특정한 인터페이스를 만듭니다.

interface SomeStrategy {
   void doSomething(StrategyData data);
}

interface StrategyData {
   String getProperty1();

   String getProperty2();
} 

이를 통해 도메인 클래스가 해당 인터페이스를 구현하거나 어댑터 패턴을 사용할 수 있습니다. 나는 이것이 단지 그것을 위해 인터페이스를 만드는 훨씬 더 깨끗한 접근법이라는 것을 알았습니다.

설계는 항상 불확실성을 줄여야합니다. 그것을 위해 인터페이스를 만드는 것은 불확실성을 줄이지 않습니다. 실제로는 의미가 없기 때문에 혼란이 증가 할 수 있습니다.

엔티티의 일대일 인터페이스는 반포 방지입니다

제임스 그레고리는 나보다 더 잘 넣었습니다 여기.

나는 당신과 동의합니다. 인터페이스는 계약으로 작동해야하므로 도메인 엔티티와 일대일 인터페이스를 갖는 가치가 없습니다. 특정 행동을 추상화하고 싶다면 유용 할 수 있습니다. 그러나 이것은 어떤 경우에는 효과가 있습니다.

왜 이것이 어리석은가?

Charlie Martin이 말했듯이 도메인 객체에 대한 인터페이스가있는 것을 발견하면 구현을 선택할 수 있습니다.

기본적인 예는 객체에 대한 식별자 (Object.ID)이며, 해당 객체를 저장하는 위치에 따라 다릅니다. 그리고 나중에 데이터 구현에서이를 작성하는 책임은 나중에 데이터를 구현할 수 있거나 없을 수 있습니다. SQL Server에서는 Autonumber를 사용할 수 있지만 Azure 테이블 스토리지에서는 안내를 할 수 있지만 데이터를 저장하는 위치를 변경하기 때문에 앱의 비즈니스 로직을 변경하지 않아도됩니다.

내 도메인 객체를 지속하거나 프레젠테이션 계층에서 사용하도록 선택하거나 선택하지 않을 수도 있습니다. 가장 좋은 앱의 범위에 따라 다릅니다. 그러나 공통 레이어에 공통 도메인 인터페이스 세트를 추가하면 서비스에 대한 서비스를 작성하고 반복해서 재사용 할 수 있습니다.

우리는 IADDRESS를 얻지 못했다면 주소가 무엇인지에 대해 같은 주장을 할 것입니다. 새로운 프로그래머는 ICREDITCARD의 경우 신용 카드를 다시 작성할 것입니다.

패턴 방지 레이블은 언어를 잘못 사용하는 것이며 복잡하고 다양한 작업에 대한 솔루션의 가치를 설명하기위한 과도한 단순화입니다.

대부분의 패턴에 대한 장소가 있습니다. 악성 싱글 톤조차도 적어도 용어가 제안한 한 "반포 팬"이 아니라는 것을 의미합니다.

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