Arquitetura e desenho de software

Responsabilidades, estilos, vistas UML, reutilização e decisões de desenho detalhado.

TLDR

Perguntar sobre esta página

ChatGPTClaudePerplexityGrokGeminiCopiar e abrirDeepSeekCopiar e abrir

A aplicação tem ecrãs, regras de reserva, armazenamento e uma API externa de horários. A arquitetura define os elementos principais, as suas responsabilidades e relações, e os princípios que orientam a evolução. O desenho detalhado decide como cada elemento cumpre essas responsabilidades.

A questão decisiva é onde confirmar a reserva de Ana: o telemóvel apresenta o pedido, mas o servidor conhece as tentativas de todos os dispositivos.

Requisitos que orientam a arquitetura

Um requisito arquiteturalmente significativo influencia a estrutura ou uma decisão difícil de alterar: suportar vários dispositivos, manter dados coerentes ou funcionar sem rede pode exigir decisões distintas.

Para a aplicação, precisamos de impedir reservas simultâneas sobrepostas. Uma verificação no ecrã não chega, porque outro dispositivo pode reservar depois dessa verificação. Por isso colocamos a decisão final no servidor, que controla os dados e confirma ou recusa numa operação atómica.

A arquitetura não fica automaticamente correta por usar um padrão conhecido. Precisamos de a avaliar nos cenários críticos. Um protótipo vertical que cria uma reserva desde o ecrã até aos dados pode revelar riscos de integração antes de construir todos os ecrãs.

Coesão, acoplamento e ocultação

A coesão descreve a relação entre as responsabilidades de um módulo. Um serviço de reservas que valida intervalos e coordena reservas tem responsabilidades relacionadas. Misturar aí desenho de botões e exportação de imagens dificulta a compreensão.

O acoplamento descreve dependências entre módulos. Não tentamos eliminar todas: a apresentação precisa de obter dados. Tentamos tornar as dependências explícitas e evitar que uma mudança interna obrigue a alterar muitos consumidores.

A ocultação de informação esconde decisões que podem mudar atrás de uma interface. O serviço pede criar uma reserva através de um contrato; não precisa de saber os nomes das tabelas. Trocar o armazenamento pode assim preservar os consumidores.

Um contrato define o que o chamador fornece, o que a operação garante e que falhas podem ocorrer. A interface deve especificar resultados e falhas. “Guardar” sem explicar conflito ou indisponibilidade deixa o chamador sem saber como agir.

Estilos e padrões

OrganizaçãoIdeiaQuando ajudaCusto ou limite
CamadasAgrupar responsabilidades por nível de abstraçãoSeparar apresentação, regras e acesso a dadosDependências mal escolhidas podem criar atalhos e rigidez
Cliente-servidorClientes pedem serviços a uma autoridade remotaPartilhar dados e controlo entre dispositivosRede, disponibilidade e segurança passam a importar
MVCSeparar modelo, vista e controlo da interaçãoAlterar apresentação sem espalhar regrasÉ preciso definir responsabilidades concretas
Pipes and filtersEtapas transformam dados ao longo de um fluxoProcessamento sequencial de dadosConversão e coordenação entre etapas podem custar
Repositório centralSubsistemas partilham um repositório de dadosIntegrar ferramentas sobre informação comumEsquema e disponibilidade criam dependências comuns

Uma arquitetura pode usar vários estilos. A aplicação pode ser cliente-servidor fisicamente e organizada em camadas em cada lado. Não são alternativas exclusivas.

Numa arquitetura de camadas estrita, uma camada usa a seguinte. Numa versão relaxada, pode usar camadas inferiores não adjacentes. O atalho pode reduzir passos, mas aumenta as dependências que precisamos de justificar.

Um repositório arquitetural partilhado por subsistemas não é exatamente o mesmo conceito que uma classe Repository que encapsula acesso a dados numa aplicação.

Um fluxo de processamento e uma interface interativa

Para importar horários de vários ficheiros, podemos decompor o processamento em ler registos, normalizar datas, rejeitar linhas inválidas e agrupar horários por sala. Cada etapa recebe um formato e produz o formato acordado para a seguinte. Pipes and filters torna visíveis estas transformações e permite testar ou substituir uma etapa sem redesenhar todas.

Não significa que o fluxo seja automaticamente adequado a qualquer parte da aplicação. O ecrã de pesquisa reage a escolhas, apresenta um estado e permite voltar atrás; separar modelo, vista e controlo da interação pode ser mais útil aí. O mesmo sistema pode ter uma interface MVC e um importador pipes and filters, implantados numa organização cliente-servidor.

Antes de ligar os filtros, definimos o contrato entre etapas: formato das datas, fuso horário e tratamento das linhas rejeitadas. Se um filtro produz datas locais e o seguinte as interpreta como UTC, o fluxo pode estar bem desenhado e produzir horários errados. O padrão organiza responsabilidades; os contratos e os cenários dão evidência da correção.

Vistas e UML

Uma vista destaca um conjunto de preocupações. O modelo 4+1 usa cenários para relacionar quatro vistas:

VistaPerguntaDiagramas possíveis
LógicaComo repartimos responsabilidades e abstrações?Classes e pacotes
ImplementaçãoComo organizamos unidades de desenvolvimento?Componentes
ProcessoQue atividades e processos interagem em execução?Atividades e interações
ImplantaçãoOnde correm os elementos e como comunicam?Implantação
Casos de uso, +1Que cenários atravessam e validam estas decisões?Casos de uso e descrições

Um pacote agrupa elementos do modelo. Um componente encapsula uma parte modular e expõe interfaces fornecidas e requeridas. Um artefacto é uma peça concreta, como um executável ou um ficheiro de configuração. Um nó é um recurso de execução onde podemos implantar artefactos.

Na aplicação, o pacote Reservas agrupa conceitos e serviços. Um componente API oferece operações de reserva. O artefacto do servidor corre num nó servidor; o artefacto móvel corre no telemóvel. Um pacote não é um computador, e uma classe não precisa de corresponder a um componente implantável.

Vista lógica e vista de implantação das reservasA Apresentação depende do Serviço de reservas, que depende do Acesso a dados. O artefacto móvel corre no telemóvel e o artefacto do servidor corre no servidor, ligados por um caminho de comunicação.Vista lógicaApresentaçãoServiço de reservasAcesso a dadosVista de implantaçãonó telemóvelapp móvelnó servidorservidorbase de dadosrede
Lógica responde quem depende de quem: as setas apontam para o elemento usado. Implantação responde onde corre cada artefacto: a linha contínua é o caminho de comunicação, sem direção. A interface ReservaAPI expõe criarSeLivre e declara o conflito como resultado possível.

Leitura da figura. Na vista lógica, a Apresentação depende do Serviço de reservas, que depende do contrato de Acesso a dados. Na vista de implantação, o artefacto móvel corre no nó telemóvel e o artefacto do servidor corre no nó servidor. A interface ReservaAPI expõe criarSeLivre e declara o conflito como resultado possível. O artefacto é o ficheiro instalado. O nó é a máquina que o executa.

Um desenho para a aplicação

Podemos separar:

  1. A apresentação mostra salas, recolhe escolhas e apresenta estados de espera, sucesso e falha.
  2. O serviço de reservas aplica regras e coordena a criação.
  3. O acesso a dados concretiza consultas e alterações através de um contrato.
  4. Um adaptador isola a API externa de horários.

A interface de dados deve permitir criarSeLivre como operação atómica. Se oferecermos apenas consultar e guardar, o serviço pode não conseguir preservar a regra de concorrência. Uma fronteira mal desenhada precisa de ser revista.

Numa aplicação Flutter com MVVM, Model-View-ViewModel, a View apresenta o estado e passa ações à ViewModel. A ViewModel prepara o estado da interface e coordena operações. Repositories gerem os dados da aplicação, e Services isolam fontes externas. Uma camada de domínio pode ajudar com regras complexas ou partilhadas, mas não é obrigatória em todas as funcionalidades.

Reutilização

Reutilizar pode envolver funções, bibliotecas, componentes, frameworks, serviços ou sistemas completos. Avalia adequação funcional, interfaces, qualidade, licença, suporte, atualizações e custo de integração.

Uma biblioteca oferece operações que a aplicação chama. Um framework organiza parte da execução e chama o código da aplicação nos pontos previstos. Esta mudança de quem controla as chamadas é uma forma de inversão de controlo.

Para autenticação, uma solução mantida pode reduzir erros de implementação. Continuamos responsáveis pela configuração, autorização e tratamento de falhas. As regras específicas das salas também continuam a exigir conhecimento do domínio, mesmo quando usamos componentes existentes.

Desenho detalhado e decisão justificada

O desenho detalhado escolhe classes, operações, algoritmos e estruturas de dados. Deve manter regras coerentes, invariantes e responsabilidades compreensíveis.

A duração válida de uma reserva exige fim posterior ao início e duração dentro do limite. Centralizar essa regra evita que o ecrã e o servidor discordem. A validação da interface melhora o feedback; a validação na autoridade dos dados preserva a regra.

Regista uma decisão com contexto, alternativas, escolha e consequências.

CampoExemplo da reserva
ContextoDois dispositivos podem pedir o mesmo intervalo
AlternativasVerificar no ecrã; verificar e criar no servidor
EscolhacriarSeLivre atómica no servidor
ConsequênciasRegra preservada; ecrã precisa de tratar o conflito

Podemos limitar uma troca de armazenamento ao Acesso a dados se a nova implementação conservar o contrato: atomicidade, resultados e falhas acordados. Esconder os nomes das tabelas, por si só, não chega.

Se a interface só oferecesse consultar e guardar, seria preciso rever o contrato para permitir a confirmação atómica. O alcance da mudança depende da decisão que falhou; um erro arquitetural não exige sempre reescrever o sistema inteiro.

Exercícios

Distribuir responsabilidades e execução

A apresentação corre no telemóvel. O serviço de reservas e o acesso a dados correm no servidor. Esboça a vista lógica e a vista de implantação, identificando dependências, nós, artefactos e comunicação. Três responsabilidades exigem três máquinas? Justifica.

Pista
Separa quem depende de quem de onde cada parte corre.
Solução

Na vista lógica, Apresentação depende de Serviço de reservas, que usa o contrato de Acesso a dados. Na implantação, o nó telemóvel recebe o artefacto móvel e o nó servidor recebe o artefacto que implementa serviço e acesso a dados. Uma ligação de rede liga os nós. Não são necessárias três máquinas: responsabilidades lógicas distintas podem partilhar o mesmo recurso de execução. A separação lógica permite discutir mudanças e contratos mesmo quando não há uma fronteira de rede.

Confere a tua resposta:

  • Representei apresentação, serviço e acesso a dados numa vista lógica.
  • Coloquei os artefactos móvel e servidor nos respetivos nós de implantação.
  • Representei a comunicação de rede sem confundir módulo com máquina.
  • Expliquei como três responsabilidades lógicas podem correr em dois nós.

Erros frequentes

Não confundas pacotes lógicos com máquinas. Não precisas de pôr cada classe como nó.

Voltar à explicação
Um contrato que não protege a regra

O armazenamento só oferece consultarDisponibilidade e guardarReserva. O serviço chama os dois em sequência. Explica o risco e uma alteração ao contrato.

Pista

Dois chamadores podem ler o mesmo estado antes de qualquer gravação.

Mais uma pista

O contrato precisa de expressar a operação que preserva a regra.

Solução

Ambas as tentativas podem ler livre antes de qualquer gravação e depois guardar duas reservas. O contrato deve oferecer criarSeLivre com semântica atómica: devolve reserva criada ou conflito, sem estado intermédio observável. A implementação garante essa semântica nos dados partilhados. Só mudar o nome sem atomicidade mantém a corrida.

Confere a tua resposta:

  • Descrevi outra gravação entre consulta e gravação.
  • Propus criarSeLivre com verificação e criação atómicas.
  • Mantive confirmação na autoridade dos dados.

Erros frequentes

Um nome novo sem garantia atómica não resolve a corrida. Desativar um botão num dispositivo não coordena outros dispositivos.

Voltar à explicação
Importar dados e reagir ao utilizador

Um importador lê ficheiros, normaliza datas, rejeita linhas inválidas e agrupa sessões por sala. A interface permite filtrar sessões e alterar a seleção. Propõe uma organização para cada parte e justifica. A normalização entrega «14:00» no fuso Europe/Lisbon, mas o agrupamento interpreta-o como UTC. Admitindo nesse dia uma diferença de uma hora, que contrato e que caso de integração expõem o erro? Usar o padrão escolhido impede esse defeito?

Solução

Pipes and filters ajusta-se ao importador: cada filtro concretiza uma transformação e entrega um formato acordado ao seguinte. MVC pode separar estado, apresentação e resposta às escolhas na interface. Não são escolhas exclusivas para o sistema inteiro.

O contrato deve indicar se a hora é local ou UTC, incluindo o fuso ou uma representação inequívoca. Neste dia, 14:00 em Lisboa corresponde a 13:00 UTC. Um teste passa uma sessão de referência pela normalização e pelo agrupamento reais e confere o instante final: interpretar 14:00 como UTC desloca-o uma hora. O padrão não escolhe nem verifica este contrato por nós.

Confere a tua resposta:

  • Propus filtros para as transformações sucessivas e MVC para a interação.
  • Expliquei que os estilos podem coexistir no mesmo sistema.
  • Fixei formato e fuso horário no contrato entre etapas.
  • Escolhi um caso de integração que revela a interpretação errada de datas.
Voltar à explicação

À tua maneira

Aparência

Modo de cor
Tema
Cor de destaque

Leitura

Fonte de leitura

Álgebra, lógica e uma ideia de cada vez.

Código

Fonte do código

Navegação

Cursor de leitura, sem edição. h, j, k, l movem; / pesquisa nesta página. v seleciona caracteres; V seleciona linhas; y copia. Tab permite destacar ou comentar. Espaço ou Enter abre blocos recolhíveis. Nos cartões, h, j, k, l mudam o foco.

CSS personalizado

Ativa uma sugestão ou guarda o teu CSS. Só muda este navegador.

Usa --page, --text e --accent para acompanhar o tema.

Seletores e recuperação

.site-header, .prose, .course-card, [data-reading-history], [data-playground] e .page-actions.

Abre a aparência com a tecla vírgula ou no rodapé. Se o CSS esconder os controlos, abre esta página sem CSS personalizado.

Pesquisar

Escreve para pesquisar em todo o site.

para escolher · Enter para abrir · Esc para fechar

Copiar fórmula

A cópia automática não está disponível. Copia o LaTeX abaixo.

Pesquisar nesta página

Enter procura · n / N repetem · Esc cancela. Ctrl / Cmd K pesquisa todo o site.

Atalhos de teclado

Clica numa tecla para a mudar. Esc cancela. Backspace desativa.

PesquisarCtrl / Cmd K

Os atalhos não interferem enquanto escreves. Tab e Enter funcionam sempre.