Skip to content

VitorDie/DesignPatterns-Grupo4

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Com certeza! Baseado na excelente refatoração que você preparou, elaborei o preenchimento da atividade em formato Markdown. O texto utiliza os padrões que você implementou (Singleton, Command e Facade) como exemplos centrais.

Você pode copiar e colar o conteúdo abaixo diretamente em um arquivo README.md.

Atividade: Aplicação de Design Patterns em Projeto de Software

Introdução ao Tema (Design Patterns)

Design Patterns (Padrões de Projeto) são soluções reutilizáveis, testadas e comprovadas para problemas recorrentes no design de software. Eles não são algoritmos ou trechos de código específicos, mas sim modelos ou "templates" que descrevem como estruturar classes e objetos para resolver um determinado tipo de problema de forma eficiente e elegante.

A utilização de Design Patterns traz benefícios significativos para o desenvolvimento de software, como:

  • Reutilização de Código: Soluções comprovadas podem ser adaptadas para diferentes contextos.

  • Legibilidade e Manutenibilidade: O código se torna mais fácil de entender para desenvolvedores que conhecem os padrões.

  • Extensibilidade: Facilita a adição de novas funcionalidades sem impactar o código existente.

  • Qualidade Arquitetural: Promove uma arquitetura mais robusta, desacoplada e coesa.

Os padrões são geralmente classificados em três categorias principais:

  1. Criacionais: Focam nos processos de criação de objetos, permitindo que um sistema seja independente de como seus objetos são criados, compostos e representados.

    • Exemplos: Singleton, Factory Method, Abstract Factory, Builder.
  2. Estruturais: Lidam com a composição de classes e objetos para formar estruturas maiores e mais complexas, mantendo a flexibilidade e eficiência.

    • Exemplos: Facade, Adapter, Decorator, Composite.
  3. Comportamentais: Concentram-se na comunicação e na atribuição de responsabilidades entre os objetos, descrevendo como eles interagem e distribuem o trabalho.

    • Exemplos: Command, Strategy, Observer, Iterator.

Padrões Escolhidos e Implementados no Projeto

Para a refatoração do servidor AgentK-Server, foram aplicados três padrões de projeto que, combinados, resolveram problemas de performance, organização e manutenibilidade.

1. Padrão Singleton (Criacional)

O Problema: A cada requisição recebida pela API, novas instâncias das classes K8sExtractor e K8sApplier eram criadas. Esse processo é custoso, pois envolve carregar a configuração do Kubernetes e estabelecer conexão com a API do cluster, resultando em lentidão e consumo desnecessário de recursos.

A Solução com Singleton: O padrão Singleton garante que uma classe tenha apenas uma instância e fornece um ponto de acesso global a ela. No nosso projeto, isso foi implementado no arquivo server/services.py, que inicializa as instâncias k8s_applier e k8s_extractor uma única vez quando o servidor é iniciado. Essas instâncias são então importadas e reutilizadas por todo o resto da aplicação, eliminando a sobrecarga de recriação.

Benefícios:

  • Performance: Melhora drástica na velocidade de resposta das requisições.

  • Gerenciamento de Estado: Garante um ponto central e único de acesso aos serviços Kubernetes.

  • Controle de Recursos: Evita o consumo excessivo de memória e CPU.

Trade-offs:

  • A utilização de um estado global pode dificultar os testes unitários, pois os testes podem se tornar dependentes de uma instância compartilhada.

2. Padrão Command (Comportamental)

O Problema: A lógica para cada operação da API (listar, aplicar, deletar, etc.) estava diretamente acoplada ao arquivo principal (main.py). Isso tornava o arquivo extenso, difícil de ler e violava o Princípio da Responsabilidade Única (SRP), pois ele era responsável por definir a API e também por executar toda a lógica de negócio.

A Solução com Command: O padrão Command encapsula uma solicitação como um objeto, permitindo parametrizar clientes com diferentes solicitações, enfileirar ou registrar solicitações e suportar operações que podem ser desfeitas. No projeto, cada operação foi movida para sua própria classe dentro de server/commands.py (ex: ListResourceNamesCommand, ApplyYamlCommand). Cada classe possui um método execute(), que contém toda a lógica necessária para aquela operação específica.

Benefícios:

  • Desacoplamento: O "invocador" (main.py) não precisa saber nada sobre a lógica da operação, apenas como executar um comando.

  • Coesão e Responsabilidade Única: Cada classe de comando tem uma única e clara responsabilidade.

  • Extensibilidade: Adicionar uma nova funcionalidade à API se resume a criar uma nova classe de comando, sem alterar o código existente.

Trade-offs:

  • Aumento no número de classes do projeto, o que pode adicionar uma leve complexidade para sistemas muito simples.

3. Padrão Facade (Estrutural)

O Problema: Com a lógica de negócio encapsulada nos comandos, o cliente (as "tools" da API) ainda precisaria saber qual classe de comando instanciar e como executá-la para cada operação. Isso introduziria uma complexidade desnecessária na interface da aplicação.

A Solução com Facade: O padrão Facade fornece uma interface unificada e simplificada para um conjunto de interfaces em um subsistema. O arquivo server/main.py foi refatorado para atuar como uma Facade. Ele expõe funções simples e diretas (@mcp.tool) que escondem a complexidade interna de instanciar e executar os objetos de comando.

Benefícios:

  • Simplicidade: Fornece uma interface limpa e de alto nível para o cliente.

  • Redução de Acoplamento: O cliente interage apenas com a Facade, e não com os múltiplos componentes do subsistema (os comandos).

  • Legibilidade: O arquivo main.py se tornou extremamente enxuto e fácil de entender, servindo apenas como um ponto de entrada e delegação.

Trade-offs:

  • A Facade pode se tornar um "god object" se acumular muitas responsabilidades, centralizando demais o fluxo da aplicação.

Estrutura de Classes (Diagrama UML)

Abaixo está um diagrama simplificado que representa a interação entre os padrões implementados.

Snippet de código

Plain textANTLR4BashCC#CSSCoffeeScriptCMakeDartDjangoDockerEJSErlangGitGoGraphQLGroovyHTMLJavaJavaScriptJSONJSXKotlinLaTeXLessLuaMakefileMarkdownMATLABMarkupObjective-CPerlPHPPowerShell.propertiesProtocol BuffersPythonRRubySass (Sass)Sass (Scss)SchemeSQLShellSwiftSVGTSXTypeScriptWebAssemblyYAMLXML classDiagram direction LR class FastMCP { <> +listar_nomes_recursos_disponiveis_cluster() +aplicar_yaml_no_cluster() +... } class Command { <> +execute() dict } class ListResourceNamesCommand { +resources: list +execute() dict } class ApplyYamlCommand { +yaml_content: str +execute() dict } class DeleteResourceCommand { +name: str +execute() dict } class Services { <> -k8s_applier: K8sApplier -k8s_extractor: K8sExtractor +get_applier() K8sApplier +get_extractor() K8sExtractor } class K8sApplier { +apply_yaml_content() } class K8sExtractor { +list_resources_cluster() } FastMCP ..> Command : "instancia e invoca" Command <|-- ListResourceNamesCommand Command <|-- ApplyYamlCommand Command <|-- DeleteResourceCommand ListResourceNamesCommand ..> Services : "usa" ApplyYamlCommand ..> Services : "usa" DeleteResourceCommand ..> Services : "usa" Services o-- K8sApplier : "contém instância única" Services o-- K8sExtractor : "contém instância única"

Trechos de Código Ilustrativos

Padrão Singleton (server/services.py)

A instância dos serviços é criada uma única vez e exportada para ser usada em todo o projeto.

Python

Plain textANTLR4BashCC#CSSCoffeeScriptCMakeDartDjangoDockerEJSErlangGitGoGraphQLGroovyHTMLJavaJavaScriptJSONJSXKotlinLaTeXLessLuaMakefileMarkdownMATLABMarkupObjective-CPerlPHPPowerShell.propertiesProtocol BuffersPythonRRubySass (Sass)Sass (Scss)SchemeSQLShellSwiftSVGTSXTypeScriptWebAssemblyYAMLXML # server/services.py import os import logging from services.k8s.K8sExtractor import K8sExtractor from services.k8s.K8sApplier import K8sApplier # --- PONTO CENTRAL DA REATORAÇÃO --- # Resolvemos a configuração e criamos as instâncias dos serviços UMA ÚNICA VEZ. # Estas variáveis serão importadas por outros módulos, agindo como Singletons. logger.info("Inicializando serviços Kubernetes...") K8S_CONFIG_FILE = resolve_k8s_config_file() k8s_applier = K8sApplier(config_file=K8S_CONFIG_FILE) k8s_extractor = K8sExtractor(config_file=K8S_CONFIG_FILE) logger.info("Serviços Kubernetes prontos para uso.")

Padrão Command (server/commands.py)

Cada operação é uma classe com um método execute, que importa e utiliza as instâncias Singleton dos serviços.

Python

Plain textANTLR4BashCC#CSSCoffeeScriptCMakeDartDjangoDockerEJSErlangGitGoGraphQLGroovyHTMLJavaJavaScriptJSONJSXKotlinLaTeXLessLuaMakefileMarkdownMATLABMarkupObjective-CPerlPHPPowerShell.propertiesProtocol BuffersPythonRRubySass (Sass)Sass (Scss)SchemeSQLShellSwiftSVGTSXTypeScriptWebAssemblyYAMLXML # server/commands.py import logging # Importamos as instâncias já criadas do services.py from .services import k8s_applier, k8s_extractor logger = logging.getLogger(__name__) class DeleteResourceCommand: def __init__(self, resource_type: str, name: str, namespace: str): self.resource_type = resource_type self.name = name self.namespace = namespace def execute(self) -> dict: try: # Utiliza a instância singleton 'k8s_applier' result = k8s_applier.delete_resource(self.resource_type, self.name, self.namespace) return result except Exception as e: return {"success": False, "error": f"Erro ao deletar recurso: {e}"}

Padrão Facade (server/main.py)

O arquivo principal define endpoints simples que escondem a complexidade de instanciar e executar os comandos.

Python

Plain textANTLR4BashCC#CSSCoffeeScriptCMakeDartDjangoDockerEJSErlangGitGoGraphQLGroovyHTMLJavaJavaScriptJSONJSXKotlinLaTeXLessLuaMakefileMarkdownMATLABMarkupObjective-CPerlPHPPowerShell.propertiesProtocol BuffersPythonRRubySass (Sass)Sass (Scss)SchemeSQLShellSwiftSVGTSXTypeScriptWebAssemblyYAMLXML # server/main.py from mcp.server.fastmcp import FastMCP # Importa as classes de Comando que contêm a lógica from .commands import ( ListResourceNamesCommand, DeleteResourceCommand ) mcp = FastMCP("AgentK-Server") @mcp.tool() def deletar_recurso_kubernetes_cluster(resource_type: str, name: str, namespace: str = 'default') -> dict: """Remove um recurso específico do cluster Kubernetes.""" # A Facade delega o trabalho para o objeto de comando return DeleteResourceCommand(resource_type=resource_type, name=name, namespace=namespace).execute() # ... outras tools ...

Instruções de Execução

  1. Bashgit clone https://github.com/seu-usuario/DesignPatterns-NomeDoGrupo.gitcd DesignPatterns-NomeDoGrupo

  2. (Assumindo que há um requirements.txt)Bashpip install -r requirements.txt

  3. Certifique-se de que seu arquivo kubeconfig está acessível, seja através da variável de ambiente KUBECONFIG ou no local padrão (~/.kube/config).

  4. O servidor pode ser iniciado em modo stdio ou como um servidor HTTP em uma porta específica._Para executar como servidor HTTP:_Bashpython -m server.main --port 3333O servidor estará disponível na porta 3333 e pronto para receber requisições para as tools definidas.

Conclusões e Aprendizados

A aplicação dos padrões de projeto Singleton, Command e Facade transformou a arquitetura do AgentK-Server de um script monolítico e pouco performático para um sistema modular, robusto e de fácil manutenção.

O Singleton resolveu um gargalo crítico de performance, enquanto o Command organizou a lógica de negócio de forma limpa e extensível. Por fim, a Facade garantiu que a complexidade interna não vazasse para a interface da API, mantendo-a simples e intuitiva de usar.

Este trabalho prático demonstrou que os Design Patterns não são apenas conceitos teóricos, mas ferramentas poderosas que, quando aplicadas corretamente, melhoram significativamente a qualidade do software. A separação de responsabilidades alcançada torna o projeto mais resiliente a mudanças e mais fácil de ser compreendido e evoluído por outros desenvolvedores.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published