Pergunta

Eu tenho uma classe básica que subclasses derivadas herdar, ele carrega as funções básicas que devem ser o mesmo em todas as classes derivadas:

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

Agora, com base na classe derivada, eu quero 'add' mais declarações de caso para o switch. Quais são as minhas opções aqui? Posso declarar funções virtuais e apenas defini-los nas classes derivadas que vão usá-los:

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() { ... }
}

Mas isso significaria quando mudar de funções em qualquer classe derivada, eu teria de editar minha classe base para refletir essas alterações.

Existe um padrão de design especificamente para este tipo de problema? Eu comprei uma série de livros sobre Design Patterns mas estou estudando-os em base "por necessidade", então eu não tenho idéia se há tal padrão a que eu estou procurando.

Foi útil?

Solução

Você pode achar útil ler sobre Cadeia de padrão de responsabilidade e repensar sua solução dessa forma.

Além disso, você pode declarar 'doRun' como método protegido e chamá-lo no caso padrão base.

default:
   doRun(input);

E definir doRun em classes derivadas.

Este é assim chamado Template Method padrão

Outras dicas

Eu acho que o padrão que você precisa é de cadeia de responsabilidade ou talvez Estratégia combinado com uma tabela chamada dinâmica ...

A forma normal de lidar com isso é usar uma fábrica. Em linhas:

  • criar uma hierarquia de classes relacionadas que fornecem a funcionalidade.
  • criar uma classe de fábrica que leva a entrada e cria uma instância do kindf direito de classe dependendo da entrada

Agora, para ganhar pontos extras adicionados:

  • criar um esquema que reghisters aulas withn a fábrica - você precisará especificar a entrada e o tipo da classe para lidar com ele

Agora, quando a necessidade de uma nova entrada vem junto, você só derivar uma nova classe e registrá-lo com a fábrica. A necessidade para a instrução switch desaparece.

Se os seus valores do seletor são apenas números inteiros pequenos, eu iria substituir a declaração caso a uma tabela de pesquisa. (As ações no caso vai cada necessidade de ser codificado como uma função, então você pode colocar ponteiros de função na tabela). Então classes herdadas pode simplesmente adicionar entradas para a mesa. (Eu acho que a tabela teria que ser uma propriedade de instância, não pode ser estático).

Colin

Mas isso significaria quando mudar funções em qualquer classe de derivados, I teria que editar minha classe base para refletir essas alterações.

Por que isso seria verdade?

Acendo do seu comentário - então se você escolher essa abordagem, você vai ter esses problemas. Outros já publicados respostas que sugerem outras soluções -. Eu verificar isso para ver se eles ajudá-lo

solução simples ?:

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;
    }
...

... e então implementar casos adicionais na subclasse Processo (). Se você precisa para suportar mais de 2 níveis (ou seja, sub-subclasse adicionando ainda mais casos), então você vai precisar de uma tabela de expedição dinâmica.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top