2011-06-15 6 views
1

현재 발생하는 디자인 문제가 있습니다.옵션 구성 요소 기능 대 SRP

구성 요소의 계층 구조가 있다고 가정 해 보겠습니다. 이러한 구성 요소의 각이 같은 보이는 추상적 인 Component 유형에서 파생 :

public abstract class Component 
{ 
    public abstract Component Parent { get; } 
    public abstract ComponentCollection Children { get; } 
} 

가 지금은 이러한 구성 요소에 몇 가지 옵션 기능을 추가 할을, 구성 요소 계층 구조 내에서 검색 할 수있는 타고 내에서 구성 요소를 선택할 수 있습니다 예를 들어 계층 구조. 는 AND "를 선택-능력을" "-능력을 검색하는 것은"예에 의해 파생 된 구성 요소에서 관리되는 동안

public abstract class Component 
{ 
    // Other members 

    public abstract bool IsSearchable { get; } 
    public abstract bool Search(string searchTerm); 

    public abstract bool IsSelectable { get; } 
    public abstract bool Select(); 
} 

:

는이 같은 기본 클래스에서 그 옵션 기능을 제공하기 위해 나쁜 관행으로 간주됩니다 전략 패턴 사용?

어떻게 든 내게는 SRP 위반 인 것처럼 보이지만 제 생각에는 유일한 대안은 각 선택적 기능에 대한 인터페이스를 갖고이 기능을 지원하는 구성 요소에서만 구현하는 것입니다.

public bool Search(Component component, string searchTerm) 
{ 
    ISearchable searchable = component as ISearchable; 
    if(searchable != null) 
    { 
     searchable.Search(searchTerm); 
    } 
} 

당신이 선택하거나 할 것이 전략 어떤이

: 구성 요소가 특정 기능을 제공하는 경우이 내가 확인하려면이 매번 같은 코드를 작성해야하는 단점이있을 것입니다 내 생각에

더 나은 아이디어?

미리 감사드립니다.

+0

왜 당신이 지적한 단점은 component.IsSearchable()을 먼저 확인해야하는 현재 코드와 크게 다른가요? –

+0

글쎄, 잘 모르겠다. 개인적으로 나는 객체의 유형을 검사하는 것보다 속성이 더 깨끗하고 (그리고 빠를 것) 체크하는 것을 고려할 것입니다. –

+1

개념적으로 객체의 유형은 속성 (일반적으로) 중 하나이므로 문제가되지 않습니다. 성능이 문제가 될 수 있으며 아마도 C++과 같은 언어이지만 Java 나 C#에서는 그렇지 않을 것입니다. 또한 ISearchable 인터페이스를 사용하면 얻을 수있는 이점을 고려해야합니다. 검색 가능하지 않은 구성 요소도있을 수 있습니다. –

답변

1

가능한 옵션 : 검색 가능성/선택성의 구현 전략 패턴 (의존성 주입)을 통해 제공되는 경우 당신이 말한대로

, 그때 ISearchable 및 ISelectable에 대한 인터페이스가 더 나은 아이디어를 생각합니다.

이러한 인터페이스에서 전략 객체를 파생시키고 기본 구성 요소 클래스에서 getter를 구현할 수 있습니다. GetSearchable(), GetSelectable() - Component의 기본 구현이 null을 반환하거나 만약 당신이 null을 싫어하는 인터페이스).

+0

감사합니다, 나에게 합리적인 것 같습니다. 나는 이렇게하려고 할 것이다. –

0

데코레이터를 사용하지 않는 이유는 무엇입니까?

Component c = new Component(); 
var selectableAndSearchableOne = new SelectableComponent (new SearchableComponent (c)); 
+0

나는이 아이디어를 꽤 좋아하지만 어떻게 '컴포넌트'로 작업 할 때 선택/검색 기능에 액세스합니까? –

+0

이 솔루션의 잠재적 인 단점은 컴파일 타임에 작동해야한다는 것입니다. 즉 SearchableComponent가 Component에서 구성 가능해야합니다. 이 경우 제시된 바와 같이 이것은 문제가 아니지만 "c"가 실제로 검색 가능한/선택 가능한 유형인지 여부를 컴파일 타임에 알지 못하는 시나리오를 상상할 수 있습니다. 반면에 모든 구성 요소가 기본적으로 검색 가능하고 선택 가능하도록 설정하려면 실수로 컴파일 타임 오류가 발생하는 것이 좋으며 부정도 아닙니다. –

+0

나는 어떤 단점도 보지 못했다. 당신이 "내가 찾을 수있는 구성 요소를 원한다"고 말한 요청은 디자인 누출이라고 생각합니다. 그것은 복잡성을 없앴다. 구성 요소 (상위 계층에 위치)의 책임이 아닙니다. –

0

다른 한가지 : 이번에는 구성 요소의 확장 점도 알고 있습니다. 방문자와 비슷한 패턴으로

public interface IHasExtensions 
    { 
     List<Extension> Extensions { get; } 
     void Extend (Extension ext); 
    } 

    public class Component : IHasExtensions 
    { 
     List<Extension> exts = new List<Extension>(); 

     public List<Extension> Extensions 
     { 
      get { return exts; } 
     } 

     public void Extend (Extension ext) 
     { 
      exts.Add (ext); 
     } 

     void Draw() { } 
    } 

    public abstract class Extension 
    { 
     readonly protected Component _Component; 

     public Extension(Component component) 
     { 
      _Component = component; 
     } 
    } 

    public class SearchExtension : Extension 
    { 
     public SearchExtension (Component component) : base (component) 
     { 

     } 
    } 

    public class SelectionExtension : Extension 
    { 
     public SelectionExtension (Component component) : base (component) 
     { 

     } 
    } 

    public class test_fly 
    { 
     void start() 
     { 
      Component c = new Component(); 
      c.Extend (new SearchExtension (c)); 
      c.Extend (new SelectionExtension (c)); 

      var exts = c.Extensions; // I Know the extensions now 
     } 
    } 
관련 문제