2015-01-21 3 views
2

나는 오후 내내 읽는 법의 대부분을 열기/닫기 원칙에 쓰는데, 나는 그것을 완전히 이해하지 못하고있다. 여기 제가 이미 읽은 참조 된 기사가 있습니다. 뭔가 놓친 것처럼 보입니다. Understanding the Open Closed Principle 이것이 열기/닫기 원칙을 어기 는가?

  • The end of dependency injection - who creates the dependencies?
  • 의 내가 저장소에서 모든 요구에 맞게 예상되는 가장 일반적인 방법 중 일부를 노출하는 기본 일반적인 저장소 있다고 가정 해 봅시다

    1. .

      저장소

      public abstract class Repository<TModel> where TModel : class { 
          protected Repository() { } 
      
          public abstract IList<TModel> FilterBy(
           Expression<Func<TModel, bool>> filterExpression); 
          public abstract IList<TModel> GetAll(); 
          public abstract TModel GetById(int id); 
          public abstract Save(TModel instance); 
      } 
      

      그런 다음 나는 ProductRepository에 전문 싶습니다.

      ProductRepository

      public abstract class ProductRepository : Repository<Product> { 
          protected ProductRepository() : base() { } 
      } 
      

      이의 내가 여기 기본 저장소에서 필요로하는 모든이 있다고 가정하자. 그렇다면 새로운 멤버를 정의하지 않기 때문에 Open/Closed Principle을 위반하지 않는 것 같습니다.

      그러나 특별한 종류의 저장소가 필요하다면 AlertLevelConfigurationRepository라고하고 비즈니스 요구 사항에는 한 번에 하나의 AlertLevelConfiguration 만 가질 수 있다고 나와 있습니다. 따라서 저장소는 항상 현재 구성을 가져와야합니다.

      public abstract class AlertLevelConfigurationRepository 
          : Repository<AlertLevelConfiguration> { 
          protected AlertLevelConfigurationRepository() : base() { } 
      
          public abstract AlertLevelConfiguration GetCurrent(); 
      } 
      

      지금, 나는이 클래스는 조상에서 수정 된 파생 형이기 때문에 때문에이 새로운 방법의 오픈/청산 원칙을 깰 것 같은 느낌 AlertLevelConfigurationRepository. 저장소의 기본 정의가이 GetCurrent 메소드를 제공하지 않기 때문에 수정되었습니다. 게다가, 변경 레벨 구성이 잘 구성 될 수 있기 때문에 Save 메소드를 제외하고는 기본 메소드를 절대로 사용하지 않을 것이라고 확신합니다!

      마지막으로, 내가 열린/닫힌 원칙을 이해하고 있는지 궁금해하고 있으며, 어쨌든 내가 어떻게하는지 의심 스럽습니다.

      이것이 원리가 깨진 사례인지 알고 싶습니다. 원칙이 깨진 사례가 있는지 알고 싶습니다. 그렇다면 원리 자체에 대한 설명을 듣고 싶습니다.

    +1

    이 상황에서 IAlertLevelConfig에 대한 인터페이스를 생성하지 않고 AlertLevelConfigurationRepo가 Repository를 상속 받도록하십시오 및 IAlertLevelConfig를 구현합니까? IAlertLevelConfig는 GetCurrent 메서드에 대한 추상화를 제공합니다. 이 기능이 필요없는 다른 repos는이 IAlertLevelConfig를 구현하지 않습니다. – failedprogramming

    답변

    3

    "Open/Closed Principle"의 정의와 같습니다. Repository 클래스는 확장형으로 열기가 가능하지만 수정이 필요하지 않습니다. Repository 클래스를 수정할 필요없이 새로운 서브 클래스 형태로 확장하여 새로운 기능을 추가 할 수 있습니다. Alert 하위 클래스에 GetCurrent() 호출을 추가하는 것은 원칙의 "확장 열기"부분의 일부입니다.

    열기/닫기는 특정 클래스가 열기/닫기이며 전체 상속 계층이 아닙니다. 클래스를 한 번 작성하고 한 가지 이유 (단 하나의 책임 원칙) 만 변경하려고합니다.

    는 별도의 문제를 제기 :

    "게다가, 나는 바꾼다 레벨 구성 될 수 있기 때문에 나는, 저장 방법을 제외하고 주어진 기본 방법의 하나를 사용하지 않습니다 꽤 확신도 구성 가능! "

    잘못 설계된 상속 계층 구조의 표시이거나 잘못된 클래스에서 상속을 받겠다는 표시입니다. 필요하지 않거나 사용하고 싶지 않은 많은 기능을 상속하는 경우 올바른 기본 클래스가 아니거나 그 클래스가 너무 많이 수행하고 있습니다 (Single Responsibility Principle violation). 당신의 경고 클래스가 필요하지 않습니다 GetAll()GetById() 전화와 같은 - - 당신은 아마 원하는 것은

    이 기능의 일부를 캡슐화하는 별도의 클래스에 해당 기능이 종속 관계로 걸릴하기 만하면 파생 클래스에 (가정 당신은 DI를 사용하고 있습니다). 또는 해당 기능을 Repository에서 파생 된 클래스에 넣고 해당 클래스에서 파생 된 클래스가 있어야합니다 (그러나 상속 솔루션보다 Composition 솔루션을 선호합니다).

    관련 문제