# Guia de Referência: Arquitetura e Design de Software (Paulo Silveira e colaboradores)

Este guia reúne práticas de orientação a objetos, separação de responsabilidades, injeção de dependência, testes e decisões arquiteturais. O objetivo é manter o sistema simples, coeso, testável e capaz de trocar detalhes com impacto controlado.

---

## 1. Orientação a Objetos Pragmática

* **Programe para interfaces:** Dependa do comportamento contratado e evite conhecimento desnecessário da implementação.
* **Composição:** Componha comportamentos e favoreça composição sobre herança quando isso reduzir acoplamento.
* **Imutabilidade:** Prefira estado controlado e objetos simples quando mutabilidade não for necessária.
* **Modelo rico:** Evite modelos anêmicos quando regras pertencem naturalmente às entidades do domínio.
* **DDD:** Considere conceitos de domínio e linguagem ubíqua quando a complexidade de negócio justificar.

---

## 2. Baixo Acoplamento e Alta Coesão

* **Acoplamento:** A ligação entre componentes deve ser a menor e mais simples possível.
* **Coesão:** Responsabilidades de um componente devem fazer sentido juntas e mudar por razões relacionadas.
* **Separação de responsabilidades:** Não misture persistência, apresentação, integração e regra de negócio no mesmo módulo.

---

## 3. Injeção de Dependência e IoC

* **Construtor:** Injete dependências explicitamente quando forem obrigatórias e estáveis para a vida do objeto.
* **Interfaces:** Use contratos para fronteiras que precisam de múltiplas implementações ou isolamento de infraestrutura.
* **Service Locator:** Evite dependências ocultas e pontos globais de acesso quando DI torna o contrato explícito.
* **Singleton:** Use com cautela; estado global e busca de dependências dificultam teste e substituição.

---

## 4. Testes e Design

* **Teste de unidade:** Isola comportamento e dá feedback sobre acoplamento/coerência das APIs.
* **TDD:** Escrever o teste antes pode ajudar o design a emergir da forma como o código será usado.
* **Integração:** Teste as fronteiras reais entre sistemas sem substituir tudo por testes end-to-end caros e lentos.
* **Integração contínua:** Automatize o feedback de build e testes para detectar erros de integração cedo.

---

## 5. Decisões Arquiteturais

* **Layers e tiers:** Separe responsabilidades lógicas de decisões físicas de implantação.
* **MVC:** Use padrões de apresentação para desacoplar interação, controle e modelo quando fizer sentido.
* **Persistência:** Não deixe o ORM definir o modelo de negócio; trate mapeamento como detalhe técnico.
* **Integração:** Defina contratos compatíveis, considere comunicação assíncrona e preserve compatibilidade de serviços.

---

## 6. Como Usar com IA

Use este arquivo em decisões de arquitetura de aplicação, especialmente para organizar classes, dependências, testes e integrações. Peça à IA que mostre coesão, acoplamento e o ponto de composição das dependências.

---

## Diretrizes de Execução para IA

Ao criar, revisar ou reestruturar uma aplicação, garanta:

1.  **Favoreça composição e contratos claros** quando reduzirem acoplamento.
2.  **Mantenha responsabilidades coesas** e separadas por motivo de mudança.
3.  **Injete dependências explicitamente** em vez de buscá-las globalmente.
4.  **Use testes como feedback de design**, não apenas como verificação posterior.
5.  **Trate framework, ORM e transporte como escolhas substituíveis** sempre que a regra de negócio não depender deles.


---

## Roteiro de Uso Operacional com IA

1. **Contextualize o projeto:** informe domínio, stack, arquitetura atual, restrições e objetivo da mudança.
2. **Selecione o recorte:** diga qual princípio/capítulo deste guia deve orientar a tarefa; não aplique tudo ao mesmo tempo.
3. **Peça diagnóstico antes do código:** a IA deve identificar sintomas, riscos, dependências e alternativas.
4. **Defina critérios de aceite:** comportamento, testes, acessibilidade, performance, segurança ou operação conforme o tema.
5. **Implemente incrementalmente:** mudanças pequenas, reversíveis e verificadas.
6. **Faça revisão final:** peça à IA que confronte a solução com este guia e liste desvios deliberados.

### Prompt de aplicação

```text
Use este guia como referência técnica para a tarefa abaixo.
Não copie regras mecanicamente. Primeiro diagnostique o problema e selecione apenas os princípios aplicáveis.
Mostre: (1) diagnóstico, (2) decisão, (3) implementação proposta, (4) testes/verificações, (5) trade-offs e (6) checklist final.

Contexto: [DESCREVA o sistema, stack, estado atual e cenário da mudança]
Objetivo: [DESCREVA o resultado esperado e o comportamento que deve existir]
Restrições: [DESCREVA limites de escopo, compatibilidade, segurança, prazo e o que não pode mudar]
```


### Como preencher os campos

- **Contexto:** descreva o tipo de sistema, stack/versões, arquitetura atual, onde a mudança acontece e o comportamento relevante já existente.
- **Objetivo:** descreva o resultado observável que deve existir ao final, não apenas a tecnologia que você quer usar.
- **Restrições:** informe o que não pode mudar, compatibilidade, prazo, segurança, acessibilidade, performance, legado, dependências e limites de escopo.

### Exemplo preenchido

```text
Contexto: Aplicação Java possui controllers criando DAOs com new e regras de negócio espalhadas entre UI e persistência.
Objetivo: Propor uma separação de responsabilidades com dependências explícitas e um caminho incremental para melhorar testabilidade.
Restrições: Sem big-bang rewrite; manter endpoints existentes; preferir composição e injeção por construtor; testes devem guiar a migração.
```
