Existe um padrão de design concebível para qualquer programa orientado a objetos? Eu pergunto isso porque recentemente vi uma implementação de uma Door
classe com a Lock
. Fazia parte de um teste e a resposta dizia que o código está seguindo o padrão Null Object:
class Lock
{
public:
virtual void close() = 0;
virtual void open() = 0;
virtual bool is_open() const = 0;
virtual ~Lock() { }
};
class DummyLock
: public Lock
{
private:
DummyLock();
DummyLock(const DummyLock&) = delete;
DummyLock& operator=(const DummyLock&) = delete;
private:
void close() { }
void open() { }
bool is_open() const { return true; }
public:
static DummyLock m_instance;
};
class Door
{
public:
Door() : m_lock(DummyLock::m_instance) { }
Door(Lock &lock) : m_lock(lock) { }
public:
Lock& get_lock() const { return m_lock; }
private:
Lock &m_lock;
};
Isso me fez pensar: esse código segue um bom padrão de design, mesmo que a descrição seja tão simples (essa classe está projetando uma classe de porta com uma fechadura); portanto, se estou escrevendo um código mais complexo, sempre deve haver algum padrão de design que eu estou seguindo?
design
design-patterns
object-oriented
object-oriented-design
user2030677
fonte
fonte
Respostas:
Querido Deus NÃO!
Quero dizer, você pode ir em frente e dizer que qualquer código aleatório está seguindo algum padrão aleatório de XYZ, mas isso não é mais útil do que eu alegar ser o rei da cadeira do meu computador. Ninguém mais sabe realmente o que isso significa, e mesmo aqueles que sabem não respeitarão exatamente minha afirmação.
Os padrões de design são uma ferramenta de comunicação para que os programadores possam dizer a outros programadores o que foi feito ou o que deve ser feito sem gastar muito tempo se repetindo. E como são coisas que surgem várias vezes, são conceitos úteis para os programadores aprenderem "ei, fazer XYZ sempre parece surgir porque é bom / útil".
Eles não substituem a necessidade de você pensar por si mesmo, de adaptar os padrões do problema único à sua frente ou de lidar com todas as coisas inevitáveis que não se encaixam em bons baldes.
fonte
the_cult
(tm) é igualmente perigoso.Não.
Isto é o que a Gang of Four (que originalmente popularizou os padrões de design) tinha a dizer sobre isso em seu livro :
O exemplo que você mostra não faz muito de nada (não acho que foi feito, acho que foi apenas um exemplo). Por si só, ele não precisa do padrão de objeto nulo. No contexto de um programa maior, pode ser.
A abordagem errada é supor que, apenas porque foi rotulado como "padrão de design", ele deve ser bom e, em seguida, procurar mais lugares para incluir mais padrões. Use-os quando eles se ajustarem ao programa e realmente resolverem um problema para você.
fonte
Não. Os padrões de design são exatamente isso: padrões nas relações entre objetos. Em outras palavras, relacionamentos que são usados e reutilizados com frequência suficiente para que alguém dissesse "Ei, parece que estamos fazendo muito isso, vamos dar um nome". A lista de padrões de design não foi determinada de uma só vez no início do OOP e depois transmitida pelo GOF ! Eles foram descobertos e, eventualmente, documentados, e depois popularizados pelo livro.
Dito isso, grande parte dos benefícios dos padrões de design é que eles facilitam o pensamento sobre o design de software em um nível superior. Eles permitem que você deixe de se preocupar com os detalhes da implementação e pense mais sobre o cenário geral. Nesse sentido, eles o libertam das minúcias, mas também podem limitá-lo da mesma maneira que o modo como você se expressa pode ser limitado pelas palavras que conhece. Assim, pode chegar um momento em que não é um padrão de design para a maioria do que você faz simplesmente porque os padrões que você sabe que são os termos em que você pensa. Mantenha os olhos abertos para os casos em que você possa estar abusando de um padrão e onde possa precisar pensar mais profundamente sobre as melhores maneiras de fazer as coisas.
Além disso, saiba que, na prática, você geralmente não implementa um determinado padrão de design, mas reconhece o padrão em algum código existente, como uma estrutura de objeto. O conhecimento sobre padrões de design comuns facilita muito a aprendizagem de como uma estrutura se destina a ser usada, pois é possível ver os relacionamentos entre as classes nos termos que você já entende.
fonte
Os padrões de design têm duas vantagens
Os objetivos de todo programa devem ser
Dito isso, observe que todas as referências aos padrões de design de OO são "elas são boas no trabalho". Eles não são perfeitos, mas preenchem um nicho com muita eficácia. Use-os quando eles trabalham, evite-os quando não o fizerem.
Como exemplo, de "código complexo", como você mencionou na sua pergunta, use uma linguagem de script que eu escrevi. A maior parte é OO com padrões de design em todos os lugares. No entanto, quando se tratava de escrever o coletor de lixo, deixei sem cerimônia todas as pretensões de OO, porque as coisas específicas que eu precisava fazer eram mais bem modeladas como boas e antigas molduras de bits. Não existe um padrão OO em toda a coisa até escrever finalizadores, onde mais uma vez o OO começou a ser um modelo útil novamente. Sem pompa nem circunstância, o código repentinamente voltou a usar as técnicas OO novamente.
Use padrões de design sempre que eles melhorarem seu produto; evite-os quando piorarem o seu produto.
fonte
Vou reverter um pouco a tendência, porque a resposta é mais sutil do que outras respostas. Toda classe que você escreve não deve empregar um padrão de design, mas a maioria dos programas não triviais que você escreve provavelmente deveria.
Um programa não trivial sem nenhum padrão de design indica:
Ambos os cenários são altamente improváveis, sem ofensas.
Isso não significa que o padrão de design deve guiá-lo, ou que você deve inseri-lo indiscriminadamente, porque acha que ficará ruim se não o fizer. O padrão de design errado é pior que nenhum.
O que isso significa é que você deve considerar a falta de padrões de design em seu programa como um cheiro de código. Algo que faz você dar uma segunda olhada e reavaliar se seu projeto não puder ser mais limpo. Se nesse ponto você decidir deixar os padrões de design fora de um programa, isso deve ser uma decisão deliberada e informada, não por acaso.
Por exemplo, você não diz: "Preciso modelar uma porta e uma fechadura, que padrão de design devo usar?" No entanto, se você o projetou primeiro sem usar nenhum padrão de design, você deve solicitar algo mais tarde: "Eu tenho muitas verificações nulas nesse código, será que há um padrão de design que possa ajudar a gerenciá-las"?
Veja a diferença? É uma distinção sutil, mas importante.
fonte
Pergunta quebrada. Deixe-me dar uma nova definição de padrão de design que iria desfazer muitos danos liberados pelo GoF: um padrão de design é uma boa prática de codificação . É isso aí.
Qualquer módulo razoavelmente complexo terá vários padrões de design. Sempre que você armazena em cache, provavelmente é um padrão de peso mosca, mas não vou revogar o seu grau de programação se você não chamar isso. Sempre que você tem um retorno de chamada, está em algum tipo de evento / incêndio / padrão de retorno de chamada. etc. Se você tem a palavra "estático", possui um singleton. Se você possui um construtor estático, possui um padrão de fábrica. Se um recurso é passado para o seu módulo, você está usando injeção de dependência.
"Padrão de design" é um termo quebrado pouco popularizado pelo GoF, que faz parecer que todos os padrões estão no mesmo nível ou você deve usar o médico recomendado de 3 a 5 por turma. Sempre que você faz algo certo que alguém fez certo, é um padrão de design . UMA
for(;;)
é um padrão comum usado para representar um loop infinito, por exemplo.Você não deve tentar aprender vários padrões de design. O conhecimento de programação não é indexado pelos padrões de design! Em vez disso, você deve aprender a escrever um bom código lendo livros, blogs e participando de conferências em seu campo. Por exemplo, se você já está usando injeção de dependência, mas não a rotulou, pode se beneficiar de sempre usar DI ou usar uma estrutura de IoC. Ou, se você estiver tentando codificar corretamente em eventos e retornos de chamada, aprenda Haskell para se familiarizar com os padrões de design funcional e isso se torna fácil.
E se toda a sua turma lê como algo importante que alguém fez corretamente, por que você está reinventando a roda? Basta usar as coisas deles.
fonte
for(;;)
idiomático? Esse provavelmente não é o melhor exemplo de algo que alguém fez "certo".while(true)
(ouwhile(1)
) em C, C ++, Java ou C # nos meus 20 anos de programação.Você deve sempre seguir os princípios de design do OO (por exemplo, modularidade, ocultação de informações, alta coesão etc.). Os padrões de design são um nicho relativamente refinado dos princípios de design de OO, especialmente se você considerar o princípio KISS .
Padrões são soluções para problemas comuns de design. Esses problemas vêm de um dos dois lugares (ou uma mistura de ambos): o espaço do problema (por exemplo, software para gerenciar recursos humanos em uma empresa) e o espaço da solução . Um programa de OO é uma instância no espaço da solução (por exemplo, uma das muitas maneiras pelas quais você pode criar um programa de OO para facilitar o gerenciamento de RH).
Não é tão fácil saber quando usar um padrão. Alguns padrões são de baixo nível, mais próximos da codificação e do espaço da solução (por exemplo, Singleton, Null object, Iterator). Outros são motivados por requisitos no espaço do problema (por exemplo, Padrão de comando para suportar desfazer / refazer, Estratégia para suportar vários tipos de arquivos de entrada / saída).
Muitos padrões vêm da necessidade de suportar variações do software no futuro. Se você nunca precisar fazer essas variações, um padrão poderá ter um design excessivo. Um exemplo seria usar o padrão do adaptador para trabalhar com o banco de dados de RH externo existente. Você decide aplicar o Adapter porque o banco de dados atual funciona com Oracle e você pode querer oferecer suporte ao NoSQL no futuro. Se o NoSQL nunca chegar à sua organização, esse código do Adaptador poderá muito bem ser inútil. Veja YAGNI . O suporte para variações que nunca surgem é o uso indevido de um padrão de design.
fonte
Padrões são soluções comuns para problemas comuns. Estamos sempre seguindo alguns padrões, os padrões do GoF abordam os mais recorrentes. Isso é ter um entendimento e uma abordagem compartilhados conhecidos pelos engenheiros de software.
Dito isto, minha resposta é não, mas sim, você está sempre seguindo algum padrão próprio. Como o GoF coloca corretamente -
Ótima citação.
fonte
Quando estou escrevendo código, não planejo usar deliberadamente o maior número possível de padrões de design. Mas, suponho, subconscientemente, quando recebo um problema de codificação, um dos padrões de design parece se encaixar e eu apenas o uso. E às vezes nada se encaixa. O que é mais importante para mim é escrever um código que faça o trabalho e seja fácil de manter e crescer.
Aqui está um artigo sobre a aplicação dos princípios de OOD usando padrões de design e também possui exemplos de código (em C ++). Ele mostra como e quando aplicar alguns dos padrões de design para escrever código limpo.
fonte