Pergunta

Premise

Eu acredito que há uma maneira de definir objetivamente "Bom" e técnicas de design "Bad" Orientação a Objetos e que, como uma comunidade, podemos determinar quais são. Este é um exercício acadêmico. Se isso for feito com seriedade e determinação, eu acredito que pode ser de grande benefício para a comunidade como um todo. A comunidade vai se beneficiar por ter um lugar que todos nós podemos ponto de dizer: "Esta técnica é 'bom' ou 'ruim' e que deve ou não usá-lo a menos que haja circunstâncias especiais."

Plano

Para este esforço, devemos nos concentrar em princípios orientada a objetos (em oposição a funcional, baseada em conjunto, ou outro tipo de idiomas).

Eu não estou pensando em aceitar uma resposta, em vez eu gostaria as respostas para contribuir para a coleção final ou ser um debate racional das questões.

Eu percebo que isso pode controverso, mas acredito que pode passar alguma coisa. Há exceções para a maioria todas as regras e acredito que este é o lugar onde o desacordo vai cair. Devemos fazer declarações e anote exceções e objeções relevantes de dissidentes.

Base

Eu gostaria de tomar uma facada em definir "Bom" e "Bad":

  • "Good" - Esta técnica irá trabalhar pela primeira vez e ser uma solução duradoura. Vai ser fácil de mudar mais tarde e vai pagar o investimento de tempo de sua implementação rapidamente. Ele pode ser aplicado consistentemente e facilmente reconhecido por programadores de manutenção no futuro. No geral, contribui para a função boa e reduz o custo de manutenção ao longo da vida útil do produto.

  • "Bad" - Esta técnica pode funcionar a curto prazo, mas logo se torna uma responsabilidade. É imediatamente difícil mudar ou se torna mais difícil ao longo do tempo. O investimento inicial pode ser pequena ou grande, mas ele rapidamente se torna um custo crescente, tornando-se um custo afundado e deve ser removido ou contornado constantemente. É subjetivamente aplicada e inconsistente e pode ser uma surpresa ou não facilmente reconhecível por programadores de manutenção no futuro. No geral, o que contribui para aumentar o custo final de manutenção e / ou operação do produto e inibe ou previne alterações no produto. Ao inibir ou impedir a mudança, torna-se não apenas um custo direto, mas um custo de oportunidade e uma responsabilidade significativa.

de arranque

Como um exemplo do que eu acho uma boa contribuição seria parecido, eu gostaria de propor um "bom" princípio:

separação de interesses

[Breve descrição]

Exemplo

[Código ou algum outro tipo de exemplo]

Objetivos

[Explicação do que problemas este princípio impede]

Aplicabilidade

[Por que, onde e quando é que eu uso este princípio?]

Exceções

[Quando eu não usaria este princípio, ou onde pode realmente ser prejudicial?]

Objeções

[Nota opiniões divergentes ou objeções da comunidade aqui]

Foi útil?

Solução

separação de interesses

Prefere Agregação de Mixin de estilo Herança

Enquanto funcionalidade pode ser adquirida por herança de uma classe de utilitário, em muitos casos, tudo pode ser adquirida através de um membro da referida classe.

Exemplo (Boost.Noncopyable):

Boost.Noncopyable é uma classe C ++ que não tem um construtor de cópia ou operador de atribuição. Ele pode ser usado como uma classe de base para impedir que a subclasse de ser copiado ou atribuída (isto é o comportamento comum). Ele também pode ser usado como um membro direto

Converter o seguinte:

class Foo : private boost::noncopyable { ... };

Para isto:

class Foo {
    ...
private:
    boost::noncopyable noncopyable_;
};

Exemplo (objeto bloqueável):

Java introduziu a palavra-chave synchronized como uma expressão idiomática para permitir que qualquer objeto a ser usado de uma maneira threadsafe. Isso pode ser espelhado em outros idiomas para fornecer mutexes para objetos arbitrários. Um exemplo comum é estruturas de dados:

class ThreadsafeVector<T> : public Vector<T>, public Mutex { ... };

Em vez disso, as duas classes podem ser agregadas.

struct ThreadsafeVector<T> {
    Vector<T> vector;
    Mutex mutex;
}

Objetivos

A herança é freqüentemente abusada como um mecanismo de code-reutilização. Se a herança é usado para qualquer coisa além de uma relação é-um, a clareza geral do código é reduzida.

Com correntes mais profundas, classes base mixin aumentar consideravelmente a probabilidade de um cenário de "Diamond of Death", no qual uma subclasse acaba herdando várias cópias de uma classe mixin.

Aplicabilidade

Qualquer linguagem que suporta herança múltipla.

Exceções

Qualquer caso em que a classe mixin fornece ou exige que os membros sobrecarga. Neste caso, a herança normalmente implica um IS-Implementadas-In-dos termos de relacionamento, e um agregado não será suficiente.

Objeções

O resultado desta transformação pode levar a membros públicos (por exemplo MyThreadSafeDataStructure pode ter um Mutex acessível publicamente como um componente).

Outras dicas

Há alguns princípios bem compreendidos que pode formar um bom ponto de partida:

Também é uma boa idéia para estudar padrões de projeto existentes para encontrar os princípios por trás deles, o mais importante é (geralmente) preferem composição sobre herança.

Eu acho que a resposta curta é que "boas" designs OO são robustas sob mudança, com a quebra menos código para qualquer mudança requisitos. Se você considerar todas as regras habituais, todos eles tendem a essa mesma conclusão.

A dificuldade é que você não pode avaliar a "bondade" do projeto sem contexto; que é, creio eu, um teorema que para qualquer modularização, existe uma mudança nos requisitos que irão maximizar a quebra, fazendo com que todas as classes de ser tocado em cada método.

Se você quiser ser rigoroso sobre isso, você pode desenvolver uma coleção de "casos de mudança" e encomendá-los em ordem de probabilidade, de modo que você minimizar a quebra para as maiores variações de probabilidade.

Na maioria dos casos, porém, alguma intuição bem desenvolvida ajuda muito: de dispositivo específico ou específicas plataforma coisas tendem a mudar, regras de negócio e processos de negócios tendem a mudança, enquanto as implementações de, digamos, aritmética, mudança muito raramente . (Não, como você pode imaginar, nunca mais. Considere, por exemplo, um sistema de negócios que podem ou não ser capaz de fazer uso da aritmética BCD suportado-plataforma.)

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