2012-09-17 4 views
18

없이 나는 단지 세터과 같이 정의했다고 최근 인터페이스를 통해 온 : 인터페이스 : 세터 게터

public interface IAggregationView 
{ 
    DataTable SetSiteData { set; } 
} 

내가이 쿼리,이는 WebPart 마이크로 소프트에 의해 주창 관행 중 하나라고 생각됩니다 디자인 (SharePoint 용). 사실이 예제는 예제에서 직접 복사됩니다.

나는 이것을 나쁜 패턴으로보고 왜 누군가가 값을 설정하고 다시 읽을 수 없으며 setter가 항상 getter를 동반해야한다고 생각하지 않습니다. 그러나 반드시 다른 방향으로).

누구나 세터가있는 것의 이점을 설명 할 수 있는지 궁금합니다. 마이크로 소프트가이 경우에 제안 할 수있는 이유는 무엇이며, 실제로 따라야 할 좋은 패턴일까요?

+0

나는 세터를 제공하지 않는 것과 같다고 생각합니다. 이 경우 setter는 기본적으로 비공개 설정입니다. 아마도 getter도 마찬가지 일 것입니다. –

+4

중복이 아니라면 관련이있을 수 있습니다 : http://stackoverflow.com/questions/4695551/write-only-properties-whats-the-point – Habib

+1

그것은 분명히 비정상적인 패턴입니다. 접두사가 'Set ...'인 속성의 이름을 지정하는 것과 같습니다. –

답변

20

이 합리적인 수 있습니다 어디 볼 ​​수있는 두 가지 시나리오가 있습니다

  1. 그렇지 않은 얻을 값, 예를 암호에 대한; 그러나, 나는 그것이 을 위해 설계된 API는 지금까지 값을 읽을 수없는 요구 사항이 없으며, 필요한 최소한의 API

에게 노출 순수하게 제한되고 개인적으로하는 void SetPassword(string) 방법

  • 을 그것을 대체 할 것이다 첫 번째 포인트 인 Set...메소드은 소비 API가 기본적으로 속성에 값을 할당하는 자동 매퍼 인 경우 이상적이지 않을 수 있습니다. 그 시나리오에서는 속성이 실제로 바람직 할 것입니다.

    "왜 누군가가 값을 설정하고 다시 읽을 수 없게되는지 모르겠다"- 같은 요지로 누군가가 값을 설정한다고 주장 할 수 있습니다. 이미 값 (설정)을 알고 있으므로 요구 사항이 필요하지 않습니다.

    하지만 예; set-only 속성을 갖는 것은 매우 드문 경우입니다.

  • +0

    저는 실제로 비밀번호 예를 좋아합니다. 이는 당신이 이것을 원할지도 모르는 좋은 사례이지만 개인적으로도 방법을 선택합니다. 좋은 대답. – Ian

    +0

    적어도 구현 클래스가 getter를 선택적으로 추가 할 것으로 예상된다면, SetFoo 메소드 대신 setter로 사용하는 것이 좋습니다. 인터페이스는 혼자 서 있지는 않지만 클래스 패밀리에 대한 연산의 공통 하위 집합을 나타냅니다. 따라서 인터페이스를 사용하는 코드뿐만 아니라 현존하는 클래스를 살펴보고 인터페이스 디자인의 의미를 판단해야합니다. –

    +0

    @DanielEarwicker 예, 인터페이스 API가 클래스의 공용 API의 직접 하위 집합이 아닌 경우 항상 * 명시 적 인터페이스 구현 * –

    1

    필자의 경험에 비추어 볼 때, 인터페이스는 건축상의 이유로 필요하지 않기 때문에 특별한 필요성 때문에 생겨났다. 예를 들어 ASP.NET 응용 프로그램에서 사람들은 전역 상태를 유지하려고 할 때 이러한 인터페이스에서 Global.asax 생성 형식을 파생시키는 경우가 있습니다. 누군가는 응용 프로그램의 별도 부분에 초기화 값을 작성하여이를 전역 위치에 게시해야합니다.

    일반적으로 집합 전용 속성을 SetXxx 메서드로 바꾸고 메서드가 최대 한 번 호출되는지 확인합니다. 그렇게하면 필자는 냄새 (imho)가 훨씬 적은 "초기화 스타일"을 명확하게 시행합니다.

    확실히 으로 설정할 수 없습니다.은 그런 것을 만들어 내지 만 코드 검토 중에는 피하는 것이 좋습니다.

    2

    인터페이스를 구현하는 클래스는 getter를 추가 할 수 있습니다. 대부분의 속성 사용은 인터페이스 자체를 통하지 않고 구현 클래스를 통해 이루어질 수 있습니다. 어떤 경우에는 대부분의 코드가 속성을 가져오고 설정할 수 있습니다. 인터페이스의 유일한 이유는 클래스 패밀리의 메소드/속성의 공통 하위 집합에 액세스하는 공통 코드가 있기 때문일 수 있습니다. 이 코드는 getter가 아니라 setter 만 필요로합니다. 인터페이스는 그 사실을 문서화합니다.

    인터페이스는 "원자 적으로 필요합니다"(예 : 메소드 A를 호출해야하는 경우 속성 B를 읽고 속성 C를 설정해야 함) 작업 그룹을 선언하는 기능입니다.

    항상 그렇듯이 에 달려 있습니다.

    14

    인터페이스 속성에서 getset의 역할이 클래스의 역할과 약간 다릅니다.

    public interface IAggregationView 
    { 
        DataTable SetSiteData { set; } 
    } 
    
    class AggregationViewImp : IAggregationView 
    { 
        public DataTable SetSiteData { get; set; } // perfectly OK 
    } 
    

    인터페이스는 속성이 적어도공개 세터를 가져야 함을 지정한다. getter의 정의 및 액세스 가능성은 구현 클래스에 맡겨집니다.

    따라서 인터페이스 계약서에 쓰기 만하면 get을 열어 둘 수 있습니다. 공개 게터를 요구할 필요가 없습니다.

    결과적으로 인터페이스에 읽기 전용 속성을 지정할 수도 없습니다. '적어도 읽기 액세스 권한 만'.

    interface IFoo 
    { 
        int Id { get; } 
    } 
    
    class Foo : IFoo 
    { 
        public int Id { get; set; } // protected/private set is OK too 
    } 
    
    +0

    코드 예제가있는 것보다 +1 웅장합니다. –

    +0

    똑같이 중요하게 "Foo"는 즉각적인 범위 안에 구현을 적절히 캡슐화하므로 * 내부 *입니다. –

    4

    (수동) 의존성 주입에 사용하는 것이 상상할 수 있습니다. 클래스는 내부적으로 만 사용하는 공동 작업자를 삽입해야 할 수도 있습니다. 물론 클래스 생성자에서 일반적으로이 작업을 선택하지만 런타임에 공동 작업자를 변경하려는 경우가있을 수 있습니다.

    관련 문제