문제

파생 된 서브 클래스가 상속되는 기본 클래스가 있으며, 모든 파생 클래스에서 동일 해야하는 기본 기능을 전달합니다.

class Basic {
public:
    Run() {
        int input = something->getsomething();
        switch(input)
        {
            /* Basic functionality */
            case 1:
                doA();
                break;
            case 2:
                doB();
                break;
            case 5:
                Foo();
                break;
        }
    }
};

이제 파생 클래스를 기반으로 스위치에 더 많은 사례 문을 '추가'하고 싶습니다. 여기 내 옵션은 무엇입니까? 가상 기능을 선언하고 사용할 수있는 파생 클래스에서만 정의 할 수 있습니다.

class Basic {
protected:
    virtual void DoSomethingElse();
public:
    Run() {
        int input = something->getsomething();
        switch(input)
        {
            /* Basic functionality */
            ...

            case 6:
                DoSomethingElse();
        }
    }
};


class Derived : public Basic {
protected:
    void DoSomethingElse() { ... }
}

그러나 이것은 파생 된 클래스에서 기능을 변경할 때 이러한 변경 사항을 반영하기 위해 기본 클래스를 편집해야합니다.

이런 종류의 문제에 대한 디자인 패턴이 있습니까? 나는 디자인 패턴에 관한 많은 책을 구입했지만 "필요에 따라"기반으로 공부하고 있기 때문에 내가 찾고있는 패턴이 있는지 전혀 모른다.

도움이 되었습니까?

해결책

읽는 것이 유용 할 수 있습니다 책임 패턴의 체인 그런 식으로 솔루션을 다시 생각하십시오.

또한 'Dorun'을 보호 된 방법으로 선언하고 기본 기본 케이스에서 호출 할 수 있습니다.

default:
   doRun(input);

파생 클래스에서 도룬을 정의하십시오.

이것은 소위라고합니다 템플릿 메소드 패턴

다른 팁

나는 당신이 필요한 패턴이라고 생각합니다 책임의 사슬 아니면 어쩌면 전략 동적 통화 테이블과 결합 ...

이것을 다루는 정상적인 방법은 공장을 사용하는 것입니다. 개요 :

  • 기능을 제공하는 관련 클래스의 계층 구조를 만듭니다.
  • 입력을 취하고 입력에 따라 올바른 클래스의 인스턴스를 만듭니다.

이제 추가 보너스 포인트 :

  • 공장과 함께 클래스를 다시 구하는 체계를 만듭니다.이를 처리하려면 입력 및 클래스 유형을 지정해야합니다.

이제 새로운 입력이 필요한 경우 새 클래스를 도출하여 공장에 등록합니다. 스위치 명령문의 필요성이 사라집니다.

선택기 값이 작은 정수 인 경우 Case 문을 조회 테이블로 바꿉니다. (케이스의 동작은 각각 함수로 코딩되어야하므로 기능 포인터를 표에 넣을 수 있습니다). 그런 다음 상속 클래스는 테이블에 항목을 추가 할 수 있습니다. (테이블은 인스턴스 속성이어야한다고 생각합니다. 정적이 될 수는 없습니다).

콜린

그러나 이것은 파생 된 클래스에서 기능을 변경할 때 이러한 변경 사항을 반영하기 위해 기본 클래스를 편집해야합니다.

왜 이것이 사실일까요?

나는 당신의 의견에 비추고 있습니다. 그러면이 접근법을 선택하면 이러한 문제가 있습니다. 다른 사람들은 다른 솔루션을 제안하는 답변을 게시했습니다. 나는 그들이 당신을 돕는 지 확인하기 위해 이것들을 확인합니다.

а 간단한 해결책 :

class Basic {
  public:
    void Run() {
      const int input = ...
      if (!(BaseProcess(input) || Process(input))) ...
    }

    vitual bool Process(int input) { return false; }

    bool BaseProcess(int input) {
      switch(input) {
    ...
        default: return false;
      }
      return true;
    }
...

그런 다음 서브 클래스 프로세스 ()에서 추가 사례를 구현하십시오. 2 개 이상의 레벨을 지원 해야하는 경우 (예 : 더 많은 사례를 추가하는 서브 스 클래스가 추가) 동적 디스패치 테이블이 필요합니다.

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