Python Design Pattern

Visão geral

O desenvolvimento de software moderno precisa atender a requisitos de negócios complexos. Ele também precisa levar em consideração fatores como extensibilidade e capacidade de manutenção futuras. Um bom projeto de um sistema de software é vital para atingir esses objetivos. Os padrões de projeto desempenham um papel importante em tais sistemas.

Para entender o padrão de design, vamos considerar o exemplo abaixo -

  • O design de cada carro segue um padrão de design básico, quatro rodas, volante, o sistema de acionamento principal como acelerador-freio-embreagem, etc.

Assim, todas as coisas repetidamente construídas / produzidas, inevitavelmente seguirão um padrão em seu design .. carros, bicicletas, pizzas, caixas eletrônicos, o que for ... até mesmo seu sofá-cama.

Projetos que quase se tornaram uma forma padrão de codificar alguma lógica / mecanismo / técnica em software, portanto, passaram a ser conhecidos ou estudados como Padrões de Projeto de Software.

Por que o Design Pattern é importante?

Os benefícios de usar Design Patterns são -

  • Ajuda a resolver problemas comuns de design por meio de uma abordagem comprovada.

  • Sem ambigüidade no entendimento, pois são bem documentados.

  • Reduza o tempo geral de desenvolvimento.

  • Ajuda você a lidar com futuras extensões e modificações com mais facilidade do que antes.

  • Podem reduzir erros no sistema, pois são soluções comprovadas para problemas comuns.

Classificação de Design Patterns

Os padrões de design GoF (Gang of Four) são classificados em três categorias, nomeadamente criativas, estruturais e comportamentais.

Padrões de Criação

Os padrões de design criacionais separam a lógica de criação de objetos do resto do sistema. Em vez de você criar objetos, os padrões de criação os criam para você. Os padrões de criação incluem Abstract Factory, Builder, Factory Method, Prototype e Singleton.

Padrões de criação não são comumente usados ​​em Python por causa da natureza dinâmica da linguagem. Além disso, a própria linguagem nos fornece toda a flexibilidade de que precisamos para criar de uma forma suficientemente elegante, raramente precisamos implementar algo no topo, como singleton ou Factory.

Além disso, esses padrões fornecem uma maneira de criar objetos enquanto ocultam a lógica de criação, em vez de instanciar objetos diretamente usando um novo operador.

Padrões Estruturais

Às vezes, em vez de começar do zero, você precisa construir estruturas maiores usando um conjunto existente de classes. É aí que os padrões de classes estruturais usam herança para construir uma nova estrutura. Os padrões de objetos estruturais usam composição / agregação para obter uma nova funcionalidade. Adaptador, Ponte, Composto, Decorador, Fachada, Peso Fly e Proxy são Padrões Estruturais. Eles oferecem as melhores maneiras de organizar a hierarquia de classes.

Padrões comportamentais

Os padrões comportamentais oferecem as melhores maneiras de lidar com a comunicação entre objetos. Os padrões que se enquadram nestas categorias são: Visitante, Cadeia de responsabilidade, Comando, Intérprete, Iterador, Mediador, Memento, Observador, Estado, Estratégia e método de modelo são padrões comportamentais.

Por representarem o comportamento de um sistema, geralmente são usados ​​para descrever a funcionalidade dos sistemas de software.

Padrões de design comumente usados

Singleton

É um dos padrões de design mais controversos e famosos. É usado em linguagens excessivamente orientadas a objetos e é uma parte vital da programação tradicional orientada a objetos.

O padrão Singleton é usado para,

  • Quando o registro precisa ser implementado. A instância do logger é compartilhada por todos os componentes do sistema.

  • Os arquivos de configuração estão usando isso porque o cache de informações precisa ser mantido e compartilhado por todos os vários componentes do sistema.

  • Gerenciando uma conexão com um banco de dados.

Aqui está o diagrama UML,

class Logger(object):
   def __new__(cls, *args, **kwargs):
      if not hasattr(cls, '_logger'):
      cls._logger = super(Logger, cls).__new__(cls, *args, **kwargs)
return cls._logger

Neste exemplo, Logger é um Singleton.

Quando __new__ é chamado, ele normalmente constrói uma nova instância dessa classe. Quando o substituímos, primeiro verificamos se nossa instância singleton foi criada ou não. Se não, nós o criamos usando uma super chamada. Assim, sempre que chamamos o construtor no Logger, sempre obtemos exatamente a mesma instância.

>>>
>>> obj1 = Logger()
>>> obj2 = Logger()
>>> obj1 == obj2
True
>>>
>>> obj1
<__main__.Logger object at 0x03224090>
>>> obj2
<__main__.Logger object at 0x03224090>