UA4 — Projetar a Solução
Projeto de software é o processo de traduzir requisitos em uma especificação técnica concreta. A primeira e mais importante decisão é a arquitetura — depois vem a decomposição modular e a documentação do que foi decidido.
Projeto de software vs. Arquitetura de software
São conceitos distintos mas complementares: arquitetura refere-se às estruturas de alto nível do sistema, às decisões estruturais fundamentais caras de mudar após implementadas (Bass; Clements; Kazman, 2012). Projeto de software é o processo mais amplo de criar a especificação de um artefato, incluindo componentes de baixo nível, algoritmos e a arquitetura como ponto de partida.
Cinco características da arquitetura de software
Atender stakeholders
Gerentes, usuários, operadores — cada parte interessada tem necessidades. A arquitetura equilibra e endereça todas essas preocupações.
Separação de necessidades
A complexidade é reduzida separando as necessidades em diferentes pontos de vista (vistas arquitetônicas), cada um descrevendo o sistema de um ângulo.
Orientada pela qualidade
A arquitetura é guiada por atributos de qualidade (RNFs): tolerância a falhas, extensibilidade, segurança, manutenibilidade, disponibilidade.
Estilos recorrentes
Padrões arquitetônicos são soluções reutilizáveis para necessidades recorrentes — evitam reinventar soluções já consolidadas.
Integridade conceitual
A arquitetura representa uma visão geral coerente. O arquiteto garante que adições ao sistema estejam alinhadas com essa visão.
Três tipos de projeto de software
| Tipo | Nível de abstração | Foco |
|---|---|---|
| Estrutural | Alto — visão abstrata | Visão geral do sistema como múltiplos componentes que interagem; domínio da solução proposta |
| Alto nível | Médio — menos abstrato | Quebra em subsistemas e módulos; estrutura modular e interação entre subsistemas |
| Detalhado | Baixo — implementação | Estrutura lógica de cada módulo, interfaces para comunicação entre módulos, algoritmos |
Modularização
Técnica para dividir o sistema em módulos independentes, capazes de executar tarefas de forma autônoma. Segue a estratégia “dividir e conquistar”. Vantagens da modularização:
- Componentes pequenos são mais fáceis de manter
- O sistema pode ser dividido com base em aspectos funcionais
- Permite o nível de abstração desejado
- Componentes com alta coesão podem ser reutilizados
- Possibilidade de execução concorrente (paralela)
- Maior segurança por isolamento
Coesão — o que é e seus 7 tipos
Coesão mede o grau de relacionamento entre os elementos dentro de um módulo. Quanto maior, melhor o design. Do mais fraco ao mais forte:
| Tipo | Descrição | Qualidade |
|---|---|---|
| Coincidental | Agrupamento não planejado; resultado de modularização arbitrária | Pior |
| Lógica | Elementos logicamente categorizados juntos, mas funcionalmente distintos | Fraca |
| Temporal | Elementos processados em um ponto de tempo similar (ex.: inicialização) | Fraca |
| Processual | Elementos agrupados e executados sequencialmente para uma tarefa | Moderada |
| Comunicativa | Elementos sequenciais que operam sobre os mesmos dados | Moderada |
| Sequencial | Saída de um elemento é entrada do próximo | Boa |
| Funcional | Todos os elementos contribuem para uma única função bem definida; reutilizável | Melhor |
Acoplamento — o que é e seus 5 níveis
Acoplamento mede o nível de interdependência entre módulos. Quanto menor, melhor o design. Do mais forte ao mais fraco:
| Nível | Descrição | Qualidade |
|---|---|---|
| Conteúdo | Um módulo acessa ou modifica diretamente o conteúdo interno de outro | Pior |
| Comum (global) | Vários módulos têm acesso de leitura e gravação a dados globais compartilhados | Ruim |
| Controle | Um módulo decide a função ou muda o fluxo de execução de outro | Moderado |
| Selo | Módulos compartilham uma estrutura de dados comum e trabalham em partes diferentes dela | Moderado |
| Dados | Módulos interagem apenas passando dados como parâmetros simples | Melhor |
A relação entre coesão e acoplamento
São métricas opostas mas complementares: buscamos alta coesão (elementos relacionados ficam juntos) e baixo acoplamento (módulos independem uns dos outros). Um sistema com coesão funcional e acoplamento de dados é bem projetado — cada módulo faz uma coisa só e se comunica com outros apenas por parâmetros.
Princípios práticos de design
DRY
Don’t Repeat Yourself. Cada pedaço de conhecimento deve ter uma representação única no sistema.
KISS
Keep It Simple. A solução mais simples que funciona é preferível à elegante que ninguém entende.
YAGNI
You Aren’t Gonna Need It. Não implemente o que não é necessário agora.
SOLID
5 princípios de OO: SRP, Open/Closed, Liskov, Interface Segregation, Dependency Inversion.
SOLID — os 5 princípios
| Letra | Princípio | Em prática |
|---|---|---|
| S | Single Responsibility | Uma classe deve ter apenas um motivo para mudar |
| O | Open/Closed | Aberta para extensão, fechada para modificação |
| L | Liskov Substitution | Subclasses substituem a superclasse sem quebrar o sistema |
| I | Interface Segregation | Muitas interfaces específicas são melhores que uma genérica |
| D | Dependency Inversion | Dependa de abstrações, não de implementações concretas |
Padrões arquitetônicos
Padrões são soluções reutilizáveis para necessidades recorrentes (Angelov; Grefen; Greefhorst, 2009). Os mais conhecidos:
Camadas / MVC
Separação em níveis horizontais; cada camada tem responsabilidade única.
Cliente-Servidor
Divisão entre quem solicita (cliente) e quem processa (servidor).
Orientado a Eventos
Componentes comunicam-se emitindo e consumindo eventos.
SOA / Microservices
Serviços autônomos com interfaces bem definidas.
Tubos e Filtros
Dados fluem por uma sequência de transformações (filtros) conectadas por tubos.
Peer-to-Peer (P2P)
Nós iguais — cada um pode ser cliente e servidor simultaneamente.
Documento de Especificação de Projeto
Toda decisão de projeto deve ser documentada. O Documento de Especificação de Projeto (padrão IEEE) contém:
| Seção | Conteúdo |
|---|---|
| Introdução | Proposta, escopo, visão geral, referencial teórico, definições/acrônimos |
| Visão geral do sistema | Descrição de alto nível do software |
| Arquitetura do Sistema | Projeto arquitetural, decomposição, projeto racional |
| Projeto de Dados | Descrição e dicionário de dados |
| Projeto de Componente | Especificação interna de cada módulo |
| Projeto de Interface | Visão geral, telas, ações e objetos |
| Matriz de Requisitos | Rastreabilidade entre requisitos e componentes |
Práticas Modernas — Projeto de Software
- ADRs (Architecture Decision Records) documentam o “por quê” de cada decisão arquitetural em arquivos Markdown versionados no Git — substituem grandes documentos de especificação que ficam desatualizados.
- Arquitetura Evolutiva (Rebecca Parsons) defende adiar decisões estruturais enquanto possível e construir “fitness functions” que verificam automaticamente se a arquitetura continua saudável.
- Domain-Driven Design (DDD) é a abordagem moderna para projeto de software: o modelo do sistema reflete o domínio de negócio usando uma linguagem ubíqua compartilhada por desenvolvedores e especialistas de domínio.
- Diagramas como código: Mermaid, PlantUML e Structurizr geram diagramas de arquitetura a partir de texto — versioning, diff e revisão em Pull Requests substituem arquivos .vsd e .drawio.
Dicas para a Prova
- Sistema de RH corporativo com acesso interno, servidor central e terminais → Cliente-Servidor. O servidor centraliza dados críticos; os terminais apenas interagem.
- Documento de Especificação de Projeto segue padrão IEEE: 7 seções incluindo Arquitetura, Projeto de Dados, Componente e Interface.
- Coesão funcional = melhor nível (todos os elementos contribuem para uma única função). Coesão coincidental = pior nível.
- Acoplamento de conteúdo = pior nível (um módulo acessa internamente outro). Acoplamento por mensagem = melhor.
- Alta coesão + baixo acoplamento = design de qualidade.
Referências bibliográficas desta UA
- BASS, L.; CLEMENTS, P.; KAZMAN, R. Software Architecture in Practice. 3. ed. Boston: Addison-Wesley, 2012.
- ANGELOV, S.; GREFEN, P.; GREEFHORST, D. A Classification of Software Reference Architectures. In: IEEE/IFIP WICSA & ECSA, 2009.
- SURYANARAYANA, G.; SAMARTHYAM, G.; SHARMA, T. Refactoring for Software Design Smells. Burlington: Morgan Kaufmann, 2015.
- LEDUR, C. L. Análise e projeto de sistemas. Porto Alegre: SAGAH, 2017.