2014-01-18 5 views
0

최근 디자인 기술을 향상시키기위한 노력의 일환으로 객체 지향적 인 디자인을 해왔습니다. 이 질문은 제가 자주 보는 특정 디자인 선택에 대한 것이며, 그 이유를 이해하지 못합니다. 나는 디자인 선택이 주관적인 경향이 있다는 것을 알고 있지만, 다른 사람들이 나의 디자인 본능이 더 좋아 지거나 더 나 빠지고 있는지 알아보기 위해 어떤 생각을하는지 알고 싶습니다.인터페이스 구현하기 인터페이스를 구현하는 객체를 리턴하는 메소드

나는 Robert C Martin(Uncle Bob) -Clean Architecture and Design-2012 COHAA The Path to Agility Conference을보고있었습니다. 이야기하는 동안 그는 Fitnesse을 개발하는 것에 관한 이야기를합니다. 나는이 소프트웨어에 익숙하지 않아서 그것을 찾아보고 the project hosted on github을 찾는다.

프로젝트를 살펴볼 때 WikiPage interface : PageCrawler getPageCrawler(); 메서드에서 내 관심을 사로 잡습니다. 그래서 나는 그 모양을보기 위해 PageCrawler interface을 찾는다. 이 인터페이스를 검토해 보면 PageCrawler의 메소드가 WikiPage에 속한 것으로 보이고 WikiPage이 인터페이스를 합리적으로 구현할 수 있다고 생각합니다.

둘을 분리하면 WikiPage에 내부가 노출되어 크롤링하는 데 필요한 정보가 페이지를 크롤링하는 개체에 액세스 할 수 있다고 생각합니다. 또한 BaseWikiPage 추상 클래스는 새로운 PageCrawlerImpl을 반환하며 내가 볼 수있는 것에서 프로젝트에 다른 PageCrawler 구현이 없습니다.

하나의 인터페이스/클래스의 메소드가 다른 클래스의 객체/클래스를 합리적으로 첫 번째 클래스에 속할 수있는 메소드로 반환하는 다른 프로젝트에서이 유형의 코드를 보았습니다. 피트니스 디자인 개발자의 의도를 알기 위해, 내가 생각해 낸이 디자인의 유일한 이유는 WikiPage을 구현하여 새로운 위키 페이지를 만드는 개발자는 크롤링 기능, 즉 크롤링 기능을 다시 구현하지 않아도된다는 것입니다 위키 페이지의 구현과 상관없이 동일해야합니다. 이런 디자인의 목적인가요? 아니면 뭔가 빠져 있습니까?

나는 Implementing an interface vs. providing an interface 질문을 찾았지만 꽤 똑같지는 않았으며, 이런 식으로 디자인 할 때 많은 통찰력을주지 못했습니다.

답변

2

인터페이스 분리 원리가 실제로 사용되고 있습니다. 당신은 PageCrawler의 인터페이스가 "이것들이 WikiPage에 속한 모든 것"이라고 생각하게 만듭니다.하지만 그것은 WikiPage를 호출하는 누군가의 관점이 아니라 구현의 관점에서 바라본 것입니다.

편집 : 아마도 인터페이스 분리 원칙과 단일 책임 원칙에 대한 내용은 적습니다.

+0

감사합니다. Jon, 나는 그렇게 생각하지 않았습니다. 그러나 ISP에 대한 나의 해석은 다릅니다. 나는 ISP가 책임감을 응집력있는 인터페이스로 분리하고 인터페이스를 구현함으로써 객체를 작성한다고 생각했다. 인터페이스를 구현하는 메소드에서 반드시 객체를 리턴하지는 않았다. 이 경우, 나는 PageCrawler 인터페이스의 존재 자체가 ISP의 사용이라고 생각하고있다. 'WikiPage'가 그것을 구현한다면,'PageCrawler' 인터페이스의 클라이언트는 여전히 구현자가'WikiPage'라는 것을 전혀 모릅니다. – TheSecretSquad

+0

게다가,'WikiPage'의 클라이언트가'PageCrawler' 메소드에 대해 알지 못한다고 말하는 것처럼 들리지만 (그래도 그 의미는 무엇입니까?), 그들은 여전히 ​​그들에게 접근 할 수 있습니다. 불필요한 메시지 ('getPageCrawler'). 예를 들어,'WikiPage'가'PageCrawler'를 구현하고,'WikiPage'가 내부적으로'PageCrawler'를 구현하는 별도의 객체에 위임하도록 선택할 수있는 데코레이터를 사용하면 더 좋지 않을까요? 나는 내 관점을 추측한다 : 그들은'WikiPage'가'PageCrawler'를 가지고 있다고 말하지만 나에게'WikiPage'는 _crawlable_이다. – TheSecretSquad

1

어떤 경우에는 개체와 "연결된"일부 기능은 개체 자체와 분리 된 상태를 유지해야합니다. .NET에서 IEnumerator<T> 메서드는 이에 대한 대표적인 예입니다. 이들의 의미는 일반적으로 연결된 IEnumerable<T>에서 파생되지만 각 열거자는 기본 컬렉션의 상태와 분리 된 상태를 유지합니다 (특히 IEnumerable<T>의 일반적인 구현은 각기 독립적 인 상태의 열거 자의 수를 알 수있는 방법이 없습니다). . 스플릿 오프 구현 이름 기본 유형들을 반영하지만, 그 기능이 다른 부재를 포함 할 수

  • : 동시에

    함께 분할 오프 인터페이스 구현의 몇 장점 연관.예를 들어, Dictionary<TKey,TValue>IEnumerable<KeyValuePair<TKey,TValue>>을 구현하지만 Keys 속성은 IEnumerable<TKey>을 구현합니다. DictionaryKeys에 의해 반환 된 것은 GetEnumerator 메서드를 가지고 있지만, 다른 하나는 키를 열거하는 반면, 하나는 키 - 값 쌍을 열거합니다.

  • 분리 된 구현이 기본 객체를 래핑하고 그것에 대한 참조를 노출하지만 일부 기능을 노출하는 경우 제한된 기능으로는 신뢰할 수 있지만 다른 기능에는 영향을주지 않는 코드에 안전하게 노출 될 수 있습니다. 객체에 대한 자유로운 참조. 경우에 따라 단일 래퍼 객체에 대한 참조를 보유하는 객체를 사용하면 원하는 수의 요청을 처리하는 데 사용할 수 있으므로 클라이언트가 래퍼 객체의 생성자를 사용하여 모든 객체에 대해 새 래퍼 객체를 만드는 것보다 효율적일 수 있습니다 의뢰.

  • 비록 Java도 .NET도 이중 상속을 허용하지 않지만 긴밀하게 연결된 각 개체가 다른 클래스로부터 상속받을 수도 있습니다.

내가 언급 한 특정 유형에 익숙하지 않아 특별한 이유가없는 것으로 알려져 있지만 그 이유는 모두 공통점입니다.

관련 문제