Composite
Introdução
O padrão Composite é um padrão de projeto estrutural que permite que objetos sejam compostos em estruturas de árvore, possibilitando que os clientes tratem tanto os objetos individuais quanto as composições de objetos de forma uniforme. Este padrão é especialmente útil em situações onde é necessário representar hierarquias de objetos, como em sistemas de arquivos ou interfaces gráficas, onde componentes podem ser agrupados e manipulados de maneira consistente.
A principal vantagem do padrão Composite é a simplificação do código que manipula estruturas complexas, permitindo que operações sejam realizadas em grupos de objetos sem a necessidade de diferenciar entre objetos simples e compostos. Isso resulta em um design mais flexível e extensível, facilitando a adição de novos tipos de componentes sem a necessidade de modificar o código existente.
Neste artefato, o subgrupo Yankee explora a aplicação do padrão Composite em um contexto específico, abordando a problemática da baixa de retrovenda e propondo uma solução que utiliza a composição de serviços para facilitar o agendamento, validação de documentos e o preenchimento de formulários. A implementação em Python é apresentada, juntamente com um diagrama UML que ilustra a estrutura do sistema.
Metodologia
Para elaboração do artefato o subgrupo Yankee realizou reuniões e discussões entre os dias 17/07 até 24/07 sendo realizada a entrega no dia 25/07. Nos primeiro dia (17) foi realizado um estudo sobre o padrão e escolhido uma problemática que ele poderia resolver, no qual optamos por fazer uma adaptação do Composite com base no Prótipo e no Diagrama de Classe. Depois entre os dias 22 a 24, foi realizada a escrita dos textos de introdução, problemática e de solução, além da construção do diagrama UML. Por fim no dia 24 foi dedicado para a implementação do UML em código Python.
Problema e Solução
Problema
O contexto de Baixa de Retrovenda foi selecionado com base nas inspirações acima, identificando o problema ao solicitar uma retrovenda e o respectivo formulário associado a ela, além das funcionalidades de Solicitar Agendamendo de Serviços e Validar Certidão ou Documento.
Solução
A seguir são apresentados o diagrama UML e ocódigo relativo à problemática em questão.
UML
Fonte: Yankee, 2024
O diagrama foi construído baseado na estrutura apresentada em sala de aula e com o auxílio do site Refactoring Guru.
Código
- Classe Servicos (servicos.py)
Esta é uma classe abstrata base que define a interface para todos os serviços. Ela utiliza o módulo abc para definir métodos abstratos.
from abc import ABC, abstractmethod
class Servicos(ABC):
@abstractmethod
def execute(self):
pass
- Classe Template (template.py)
Implementa a interface de composição de serviços.
from .servicos import Servicos as Componente
from typing import List
class Template(Componente):
def __init__(self):
self._filho: List[Componente] = []
def adicionar(self, c: Componente):
self._filho.append(c)
def remove(self, c: Componente):
self._filho.remove(c)
def getFilho(self) -> List[Componente]:
return self._filho
def execute(self):
for child in self._filho:
child.execute()
- Classe ValidarCertidaoOuDocumento (validar_certidao_ou_documento.py)
Valida certidões ou documentos específicos.
from .servicos import Servicos as Componente
class ValidarCertidaoOuDocumento(Componente):
def __init__(self, tipoPessoa: bool, numeroCertidao: int, dataCertidao: str):
self._tipoPessoa = tipoPessoa
self._numeroCertidao = numeroCertidao
self._dataCertidao = dataCertidao
def execute(self):
print(f"Validando certidão ou documento: {self._numeroCertidao}")
- Classe AgendamentoDeServico (agendamento_de_servicos.py)
Implementa a lógica de agendamento de serviços.
from .servicos import Servicos as Componente
from typing import List
class AgendamentoDeServicos(Componente):
def __init__(self):
self._agendamento: List = []
def execute(self):
print("Executando agendamento de serviços")
- Classe BaixaDeRetrovenda (baixa_de_retrovenda.py)
Implementa a lógica de baixa de retrovenda.
from .servicos import Servicos as Componente
from typing import List
class BaixaDeRetrovenda(Componente):
def __init__(self):
self._selecionarRegiao: List = []
self._selecionarSetor: List = []
self._selecionarImovel: List = []
def execute(self):
print("Executando baixa de retrovenda")
- Classe FormularioRetrovenda (formulario_retrovenda.py)
Implementa a lógica de preenchimento do formulário de retrovenda.
from .servicos import Servicos as Componente
class FormularioRetrovenda(Componente):
def __init__(self, codigo_imovel: int, numero_processo: str, alienacao: str, tamanho: int, tipoDeclaracao: bool, habitsNumero: int, habitsAno: int):
self._codigo_imovel = codigo_imovel
self._numero_processo = numero_processo
self._alienacao = alienacao
self._tamanho = tamanho
self._tipoDeclaracao = tipoDeclaracao
self._habitseNumero = habitsNumero
self._habitseAno = habitsAno
def execute(self):
print(f"Executando formulário de retrovenda para imóvel: {self._codigo_imovel}")
Resultado de exemplo
- Arquivo de teste (main.py)
from .template import Template
from .agendamento_de_servicos import AgendamentoDeServicos
from .validar_certidao_ou_documento import ValidarCertidaoOuDocumento
from .baixa_de_retrovenda import BaixaDeRetrovenda
from .formulario_retrovenda import FormularioRetrovenda
if __name__ == "__main__":
# Criando instâncias dos componentes
agendamento = AgendamentoDeServicos()
validar = ValidarCertidaoOuDocumento(tipoPessoa=True, numeroCertidao=12345, dataCertidao="01/01/2020")
baixa = BaixaDeRetrovenda()
formulario = FormularioRetrovenda(codigo_imovel=101, numero_processo="AB123", alienacao="Venda", tamanho=200, tipoDeclaracao=True, habitsNumero=456, habitsAno=2021)
# Criando uma instância de Template e adicionando componentes
template = Template()
template.adicionar(agendamento)
template.adicionar(validar)
template.adicionar(baixa)
template.adicionar(formulario)
# Executando o método execute do Template, que executa os métodos execute de todos os seus filhos
template.execute()
- Saída
Executando agendamento de serviços
Validando certidão ou documento: 12345
Executando baixa de retrovenda
Executando formulário de retrovenda para imóvel: 101
Bibliografia
GAMMA, Eric, et al. **Design Patterns: Elements of Reusable Object-Oriented Software.** 1rd ed. Indianapolis: Pearson Education, 1994.
[Refactoring Guru](https://refactoring.guru/pt-br/design-patterns/composite).
Histórico de Versão
Favor não copiar o histórico de versão dobrado, essa seção é apenas para rastrear o template de artefato
Versão | Data | Descrição | Autor(es) | Revisor(es) |
---|---|---|---|---|
1.0 |
22/07/2024 | Confecção do artefato | Yankee | Whiskey |
1.1 |
24/07/2024 | Finalização diagrama e implementação | Yankee | Papa |
1.2 |
24/07/2024 | Revisão e Correções | João Lucas | Foxtrot |