Princípio de fechamento aberto (OCP) x princípio de inversão de dependência (DIP)


12

Eu estava tentando entender a diferença entre Princípio Fechado Aberto (OCP) e Princípio de Inversão de Dependência (DIP).

Com base nas pesquisas que fiz na internet até agora, cheguei à conclusão de que 'DIP é uma opção através da qual podemos alcançar OCP'.

Eu estou certo nisso?

Você pode me dar um exemplo que não segue o DIP, mas segue o OCP?

Respostas:


16

Eu escrevi uma resposta anteriormente sobre Princípio Aberto-Fechado (OCP) vs Princípio de Substituição de Liskov (LSP) e ambos esses princípios se relacionam muito um com o outro, mas ainda são conceitualmente diferentes com alguns exemplos inventados de ter um, mas não o outro. Por causa dessa resposta, abordarei brevemente o OCP brevemente e aprofundarei o DIP e o que faz isso funcionar.

Vamos tentar discutir como o OCP se relaciona e difere do DIP (Dependency Inversion Principle), explicando primeiro os diferentes princípios.

Princípio de Inversão de Dependência

Lendo os Princípios de OOD do tio Bob, você verá que o DIP declara o seguinte:

Depende de abstrações, não de concreções.

Uma abstração em Java é simplesmente obtida com interfacee abstractkeywords, o que significa que você tem um "contrato" para alguma entidade de software que o código deve seguir. Algumas linguagens de programação não têm a capacidade de definir explicitamente comportamentos para o código seguir, portanto as abstrações devem ser seguidas de maneira mais manual, em vez de o compilador ajudá-lo a impor o contrato. Por exemplo, em C ++, você tem aulas com métodos virtuais e linguagens de programação dinâmica, como Javascript, para garantir que você use objetos da mesma maneira (embora, no caso de Javascript, isso tenha sido estendido no TypeScript, que adiciona um sistema de tipos para ajudá-lo). com contratos de escrita que são verificados pelo compilador).

O nome inclui o termo "inversão" porque, tradicionalmente (você sabe na idade das trevas da programação), você escrevia estruturas de software que tinham módulos de nível superior, dependendo dos módulos de baixo nível. Por exemplo, fazia sentido ter uma ButtonAtKitchenentrada de manipulação para a KitchenLamp1e KitchenLamp2. Infelizmente, isso tornou o software muito mais específico do que precisava e o gráfico de objetos ficaria assim:

ButtonAtKitchen manipula KitchenLamp1 e KitchenLamp2

Então, quando você tornar o software mais geral, adicionando "contratos". Observe como as setas no gráfico do objeto "invertem" a direção. Que as lâmpadas da cozinha agora dependem de um Button. Em outras palavras, os detalhes agora dependem de abstrações, e não o contrário.

O KitchenButton agora possui uma abstração de IButton em que as lâmpadas da cozinha dependem

Portanto, temos uma definição mais geral de DIP, também detalhada no artigo original de DIP por Tio Bob .

A. Os módulos de alto nível não devem depender dos módulos de baixo nível. Ambos devem depender da abstração. B. As abstrações não devem depender de detalhes. Os detalhes devem depender de abstrações.

Princípio Aberto-Fechado

Continuando com os princípios do tio Bob, você verá que o OCP declara o seguinte:

Você deve poder estender um comportamento de classe, sem modificá-lo.

Um exemplo disso é empregar o padrão Strategy em que uma Contextclasse é fechada para modificações (por exemplo, você não pode alterar seu código interno), mas também está aberta para extensão por meio de suas dependências colaborativas (por exemplo, as classes de estratégia).

Em um sentido mais geral, qualquer módulo é construído para ser extensível através de seus pontos de extensão.

Um módulo com pontos de extensão

OCP é semelhante ao DIP, certo?

Não , não mesmo.

Embora ambos estejam discutindo abstrações, são conceitualmente diferentes. Ambos os princípios estão analisando contextos diferentes, OCP em um módulo específico e DIP em vários módulos. Você pode obter os dois ao mesmo tempo que a maioria dos padrões de design do Gang of Four, mas ainda pode se afastar do caminho.

No exemplo DIP mencionado acima, com o botão e as luminárias da cozinha, nenhuma das luminárias da cozinha é extensível (nem atualmente existe nenhum requisito para explicar que precisa ser). O design está quebrando o OCP, mas segue o DIP .

Um exemplo inverso (e artificial) seria uma lâmpada de cozinha extensível (com o ponto de extensão parecido com a LampShade), mas o botão ainda depende das lâmpadas . Está quebrando o DIP, mas segue o OCP .

Não se preocupe, isso acontece

Na verdade, isso é algo que você verá acontecer frequentemente no código de produção, que parte dele pode quebrar um princípio. Em sistemas de software maiores (ou seja, qualquer coisa maior que os exemplos acima), você pode quebrar um princípio, mas mantendo o outro normalmente porque precisa manter o código simples. Na minha opinião, isso é bom para módulos pequenos e independentes, pois estão no contexto relacionado ao Princípio de Responsabilidade Única (SRP).

Uma vez que algum módulo se torna complicado, você provavelmente precisará analisá-lo com todos os princípios em mente e reprojetar ou refatorá- lo para um padrão bem conhecido.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.