Table of Contents
📘 Paradigmas de Programação e Padrões de Projeto
Domine a arte de escrever código elegante, escalável e de fácil manutenção através do estudo dos paradigmas fundamentalistas e dos padrões de projeto consagrados.
Foco do Curso
Metodologia: Abordagem prática e comparativa entre diferentes estilos de programação, seguida pela aplicação de padrões de design (GoF) em cenários reais de desenvolvimento.
🎯 O Que Você Vai Aprender
-
Paradigmas de Programação --- Compreenda as raízes da computação: do imperativo ao funcional, entenda como o "jeito de pensar" afeta a solução. Ver Módulo 1
-
Princípios de Design --- Domine o SOLID, acoplamento e coesão. Aprenda a identificar "code smells" e a projetar sistemas flexíveis. Ver Princípios
-
Padrões Criacionais --- Aprenda Singleton, Factory, Builder e outros padrões para gerenciar a criação de objetos de forma desacoplada. Ver Padrões
-
Padrões Estruturais e Comportamentais --- Organize sistemas complexos e gerencie a interação entre objetos com Adapter, Strategy, Observer e MVC. Ver Projetos
📚 Jornada de Aprendizado (16 Aulas)
O curso é estruturado em cinco trilhas evolutivas.
🧱 Módulo 1: Fundamentos dos Paradigmas (Aulas 01-04)
- Aula 01 - Introdução aos Paradigmas 🧩
- Aula 02 - Imperativo e Estruturado 🏗️
- Aula 03 - Orientado a Objetos (POO) 📦
- Aula 04 - Paradigma Funcional ⚡
🏗️ Módulo 2: Comparação e Aplicação (Aulas 05-08)
- Aula 05 - Paradigmas na Prática ⚖️
- Aula 06 - Multi-Paradigma Moderno 🌐
- Aula 07 - Princípios SOLID 📐
- Aula 08 - Problemas de Design ⚠️
🔌 Módulo 3: Padrões Criacionais (Aulas 09-11)
- Aula 09 - Intro Design Patterns 📖
- Aula 10 - Singleton, Factory, Builder 🏭
- Aula 11 - Prática Criacional 🛠️
🚀 Módulo 4: Estruturais e Comportamentais (Aulas 12-15)
- Aula 12 - Padrões Estruturais 🔗
- Aula 13 - Padrões Comportamentais 🧠
- Aula 14 - MVC e Arquitetura 🏛️
- Aula 15 - Refatoração com Padrões ♻️
🎓 Módulo 5: Projeto Final (Aula 16)
Aulas
Aulas do Curso 📚
Acesse aqui todo o conteúdo teórico dividido em módulos de aprendizado.
-
Módulo 1: Fundamentos de Backend --- A base do desenvolvimento de APIs e Microsserviços.
-
Módulo 2: Manipulação de Dados --- Implementação robusta e persistência de dados.
-
Módulo 3: Segurança e Autenticação --- Protegendo sua API contra acessos não autorizados.
-
Módulo 4: Aplicações SPA (React) --- Criando o frontend moderno para consumir sua API.
Módulo 1 – Fundamentos
Aula 01: Introdução aos Paradigmas de Programação 🧩
🎯 Objetivos da Aula
- [x] Compreender o que é um paradigma de programação.
- [x] Conhecer a evolução histórica das linguagens.
- [x] Identificar os principais problemas no desenvolvimento de software.
- [x] Ter uma visão geral dos paradigmas que serão estudados.
💡 O que é um Paradigma?
Um paradigma de programação é uma abordagem, um estilo ou uma forma de estruturar o pensamento para resolver problemas através do código. Não é uma linguagem em si, mas um modelo mental que define como o programador vê a execução do programa.
"Um paradigma é uma visão de mundo, um conjunto de conceitos e práticas que definem uma disciplina científica em um determinado período."
⌛ Evolução Histórica
A programação evoluiu de instruções binárias diretas para abstrações de altíssimo nível:
- Código de Máquina: Instruções diretas ao processador.
- Assembly: Mnemônicos para facilitar a leitura.
- Linguagens de Alto Nível (Fortran, C): Foco em procedimentos e lógica imperativa.
- Orientação a Objetos (Simula, Smalltalk, Java): Foco em modelar o mundo real.
- Declarativo/Funcional (Lisp, Haskell): Foco no "o que" fazer, não no "como".
📊 Panorama dos Paradigmas
graph TD
P[Paradigmas] --> I[Imperativos]
P --> D[Declarativos]
I --> Estruturado[Estruturado]
I --> POO[Orientado a Objetos]
D --> Funcional[Funcional]
D --> Logico[Lógico]
⚠️ Problemas Comuns no Desenvolvimento
- Complexidade: Sistemas grandes tornam-se difíceis de entender.
- Rigidez: Dificuldade em alterar o código sem quebrar outras partes.
- Fragilidade: Pequenas mudanças causam erros inesperados.
- Repetição: Código duplicado que dificulta a manutenção.
💻 Exemplo Comparativo (Soma de Lista)
Estilo Imperativo (Como fazer)
Estilo Funcional (O que fazer)
🚀 Mini-projeto: Analisador de Estilo
Nesta primeira aula, vamos apenas observar diferentes formas de resolver o mesmo problema e começar a treinar nosso "olhar arquitetural".
🎯 Próximos Passos
-
Slides
-
Quiz
-
Exercícios
-
Projeto
Aula 02: Paradigma Imperativo e Estruturado 🏗️
🎯 Objetivos da Aula
- [x] Compreender os fundamentos do paradigma imperativo.
- [x] Aprender sobre o teorema da programação estruturada.
- [x] Explorar variáveis, controle de fluxo e modularização.
- [x] Identificar vantagens e limitações desta abordagem.
💡 O Paradigma Imperativo
O paradigma imperativo é baseado na ideia de ordens (comandos) que alteram o estado do programa. Imagine uma receita de bolo: "pegue os ovos", "misture a farinha", "asse por 40 minutos".
Conceitos Chave:
- Estado: Os valores atuais das variáveis em um determinado momento.
- Comandos: Instruções que alteram o estado (atribuições, I/O).
🧱 Teorema da Programação Estruturada
Todo programa computável pode ser implementado usando apenas três estruturas básicas:
- Sequência: Instruções executadas uma após a outra.
- Seleção (Decisão):
if-else,switch. - Repetição (Iteração):
while,for.
📊 Fluxograma de Controle
graph TD
Start([Início]) --> Input[/Ler Valor/]
Input --> Decision{Valor > 10?}
Decision -- Sim --> Process[Dobrar Valor]
Decision -- Não --> End([Fim])
Process --> Output[/Mostrar Resultado/]
Output --> End
💻 Exemplo em Python (Imperativo)
# Estado inicial
contador = 1
total = 0
# Estrutura de repetição (Iteração)
while contador <= 5:
# Atribuição e alteração de estado
total += contador
contador += 1
print(f"Total acumulado: {total}")
🧠 Blocos de Destaque
Conceito: Efeito Colateral
No paradigma imperativo, funções costumam ter efeitos colaterais, ou seja, elas alteram variáveis fora de seu escopo local.
Atenção: Espaguete
O uso excessivo de comandos de salto (goto) ou lógica desestruturada pode levar ao famoso "código espaguete", difícil de manter.
🚀 Mini-projeto: Calculadora de Gastos
Vamos estruturar um pequeno script que lê gastos diários, calcula a média e aplica descontos usando apenas estruturas estruturadas.
🎯 Próximos Passos
-
Slides
-
Quiz
-
Exercícios
-
Projeto
Aula 03: Paradigma Orientado a Objetos (POO) 📦
🎯 Objetivos da Aula
- [x] Compreender os pilares da POO: Classe e Objeto.
- [x] Aprender sobre Encapsulamento, Herança e Polimorfismo.
- [x] Modelar sistemas simples usando objetos.
- [x] Comparar a abordagem OO com a estruturada.
💡 O que é POO?
A Orientação a Objetos é um paradigma que organiza o código em torno de dados (objetos) em vez de funções/lógica. Um objeto é uma "entidade" que possui características (atributos) e comportamentos (métodos).
🧱 Os 4 Pilares da POO
- Abstração: Focar apenas no que é essencial para o sistema.
- Encapsulamento: Esconder os detalhes internos e proteger os dados.
- Herança: Reutilizar comportamentos e atributos de classes pai.
- Polimorfismo: Capacidade de um objeto ser tratado de múltiplas formas.
📊 Diagrama de Classes (Herança)
classDiagram
class Animal {
+String nome
+fazerSom()*
}
class Cachorro {
+fazerSom()
}
class Gato {
+fazerSom()
}
Animal <|-- Cachorro
Animal <|-- Gato
💻 Exemplo Prático (Python)
class Veiculo:
def __init__(self, marca):
self._marca = marca # Encapsulamento (protegido)
def mover(self):
print(f"O {self._marca} está se movendo.")
class Carro(Veiculo): # Herança
def mover(self): # Polimorfismo
print(f"O carro {self._marca} está acelerando na estrada.")
meu_carro = Carro("Toyota")
meu_carro.mover()
🧠 Destaques
Dica de Modelagem
Sempre pergunte: "Isso É UM..." (para Herança) ou "Isso TEM UM..." (para Composição).
Vantagem principal
A POO brilha em sistemas grandes onde a reutilização de código e a organização modular são críticas para o sucesso.
🚀 Mini-projeto: Sistema de Biblioteca
Vamos modelar uma pequena biblioteca onde Livros e Usuários interagem através de objetos e métodos específicos.
🎯 Próximos Passos
-
Slides
-
Quiz
-
Exercícios
-
Projeto
Aula 04: Paradigma Funcional ⚡
🎯 Objetivos da Aula
- [x] Compreender o conceito de Programação Declarativa.
- [x] Aprender sobre Funções Puras e Efeitos Colaterais.
- [x] Entender a importância da Imutabilidade.
- [x] Manipular listas com funções de alta ordem (Map, Filter, Reduce).
💡 O Paradigma Funcional
Diferente do imperativo, o paradigma funcional trata a computação como a avaliação de funções matemáticas e evita mudar estados ou dados mutáveis.
Conceitos Fundamentais:
- Funções Puras: Dada a mesma entrada, sempre retornam a mesma saída e não causam efeitos colaterais.
- Imutabilidade: Uma vez criado, um dado não pode ser alterado. Cria-se um novo dado a partir do antigo.
📊 Fluxo Funcional (Map, Filter)
graph LR
Input[Lista Original] --> Filter[Filter: Pares]
Filter --> Map[Map: Dobro]
Map --> Output[Nova Lista]
💻 Exemplo Prático (Python)
numeros = [1, 2, 3, 4, 5, 6]
# Programação Declarativa / Funcional
pares = filter(lambda x: x % 2 == 0, numeros)
dobrados = map(lambda x: x * 2, pares)
print(list(dobrados)) # Output: [4, 8, 12]
🧠 Blocos de Destaque
Alta Ordem (Higher-Order)
Funções que recebem outras funções como argumento ou retornam funções. É a base da flexibilidade funcional.
Por que usar?
O código funcional tende a ser mais conciso, previsível e fácil de testar, além de ser excelente para processamento paralelo.
🚀 Mini-projeto: Analisador de Texto
Vamos criar um processador de texto que conta palavras, remove stop words e gera estatísticas usando apenas transformações de dados (sem loops for manuais).
🎯 Próximos Passos
-
Slides
-
Quiz
-
Exercícios
-
Projeto
Módulo 2 – Comparação e Aplicação
Aula 05: Comparando Paradigmas na Prática ⚖️
🎯 Objetivos da Aula
- [x] Comparar a resolução do mesmo problema em diferentes paradigmas.
- [x] Identificar vantagens e desvantagens de cada abordagem.
- [x] Entender quando escolher um paradigma sobre outro.
💡 O Desafio: Filtro e Soma
Vamos resolver o seguinte problema: "Dada uma lista de produtos, filtre os que custam mais de R$ 50,00 e calcule o valor total com um imposto de 10%."
📊 Tabela de Comparação
| Critério | Imperativo | Orientado a Objetos | Funcional |
|---|---|---|---|
| Foco | Sequência de passos | Entidades e Dados | Transformação de Dados |
| Legibilidade | Média (muitos loops) | Alta (abstração) | Altíssima (concição) |
| Manutenibilidade | Difícil em larga escala | Excelente (modular) | Ótima (previsível) |
💻 Resoluções em Python
1. Abordagem Imperativa
produtos = [10, 60, 20, 80, 50]
total = 0
for p in produtos:
if p > 50:
total += p * 1.1
print(f"Total Imperativo: {total}")
2. Abordagem Funcional
produtos = [10, 60, 20, 80, 50]
total = sum(map(lambda p: p * 1.1, filter(lambda p: p > 50, produtos)))
print(f"Total Funcional: {total}")
📊 Fluxo de Decisão
graph TD
Problem[Problema de Software] --> Complexity{Complexidade?}
Complexity -->|Baixa| Script[Imperativo/Script]
Complexity -->|Média/Alta| Model[OO/Arquitetado]
Complexity -->|Dados Intensos| Func[Funcional/Declarativo]
🧠 Blocos de Destaque
Trade-offs
Não existe "bala de prata". O estilo funcional é ótimo para processamento, mas a POO é imbatível para modelagem de domínios complexos.
Atenção
Misturar paradigmas sem critério pode tornar o código confuso. O segredo é a consistência.
🚀 Mini-projeto: Refatorador de Paradigmas
Vamos pegar um código totalmente imperativo e refatorá-lo para um estilo Híbrido (OO + Funcional), aproveitando o melhor de cada mundo.
🎯 Próximos Passos
-
Slides
-
Quiz
-
Exercícios
-
Projeto
Aula 06: Paradigmas Modernos e Multi-Paradigma 🌐
🎯 Objetivos da Aula
- [x] Conhecer o conceito de linguagens multi-paradigma.
- [x] Explorar como linguagens modernas integram diferentes estilos.
- [x] Identificar as tendências atuais no desenvolvimento de software.
💡 O que é Multi-Paradigma?
A maioria das linguagens de destaque hoje (Python, JavaScript, Java, C#, Swift, Rust) não se limita a um único paradigma. Elas permitem que o desenvolvedor utilize POO para estrutura e Funcional para manipulação de dados, por exemplo.
🧱 Exemplo: O Ecossistema JavaScript
O JavaScript é o rei do multi-paradigma:
- Imperativo: Manipulação direta do DOM.
- Funcional: map, filter, reduce em arrays.
- Orientado a Objetos: Classes (ES6+) e protótipos.
📊 Linguagens e seus Paradigmas
pie title Paradigmas nas Linguagens Modernas
"Imperativo" : 20
"POO" : 40
"Funcional" : 30
"Outros" : 10
💻 Exemplo Prático (List Comprehensions em Python)
Python usa técnicas funcionais dentro de um ambiente OO/Imperativo:
# Híbrido: List Comprehension (Funcional) + Objeto (OO)
class Aluno:
def __init__(self, nome, nota):
self.nome = nome
self.nota = nota
alunos = [Aluno("Ana", 8), Aluno("Beto", 4), Aluno("Caio", 9)]
# Estilo funcional em uma linha
aprovados = [a.nome for a in alunos if a.nota >= 6]
print(f"Aprovados: {aprovados}")
🧠 Destaques
Dica de Carreira
Saber transitar entre paradigmas é um dos diferenciais que separa um programador júnior de um sênior.
Tendência: Rust
A linguagem Rust está ganhando popularidade por combinar alto desempenho (imperativo) com segurança de memória rigorosa e conceitos funcionais avançados.
🚀 Mini-projeto: Conversor Híbrido
Desenvolva um pequeno sistema que utiliza classes para representar entidades e funções de alta ordem para processar coleções dessas entidades.
🎯 Próximos Passos
-
Slides
-
Quiz
-
Exercícios
-
Projeto
Aula 07: Princípios de Projeto de Software (SOLID) 📐
🎯 Objetivos da Aula
- [x] Compreender os conceitos de Acoplamento e Coesão.
- [x] Aprender o significado das 5 letras do acrônimo SOLID.
- [x] Aplicar boas práticas de organização de código.
💡 Acoplamento vs Coesão
- Coesão: O quanto uma classe faz apenas o que ela se propõe a fazer. (Alta coesão é boa!)
- Acoplamento: O quanto uma classe depende de outra para funcionar. (Baixo acoplamento é bom!)
🧱 O que é SOLID?
Apresentado por Robert C. Martin (Uncle Bob), são 5 princípios para tornar o software mais compreensível e flexível:
- S (SRP): Responsabilidade Única.
- O (OCP): Aberto/Fechado (Aberto para extensão, fechado para modificação).
- L (LSP): Substituição de Liskov.
- I (ISP): Segregação de Interfaces.
- D (DIP): Inversão de Dependência.
📊 Visualização SOLID
graph LR
S[Single Responsibility] --> Code[Código Limpo]
O[Open/Closed] --> Code
L[Liskov] --> Code
I[Interface Segr.] --> Code
D[Dep. Inversion] --> Code
💻 Exemplo: SRP (Violando vs Seguindo)
Violando (Uma classe faz tudo)
Seguindo (Responsabilidades divididas)
class UsuarioRepositorio:
def salvar(self, usuario):
pass
class EmailService:
def enviar(self, usuario):
pass
🧠 Blocos de Destaque
Atenção
Não tente aplicar todos os princípios SOLID de uma vez em sistemas minúsculos. O excesso de abstração pode gerar complexidade desnecessária (Overengineering).
Dica
O princípio D (Inversão de Dependência) é a base para quase todos os Padrões de Projeto que veremos em seguida.
🚀 Mini-projeto: Refatoração SOLID
Pegue uma classe "Deus" (que faz tudo) e divida suas responsabilidades em classes menores e coesas.
🎯 Próximos Passos
-
Slides
-
Quiz
-
Exercícios
-
Projeto
Aula 08: Problemas Comuns de Design ⚠️
🎯 Objetivos da Aula
- [x] Identificar os principais "sintomas" de um código ruim.
- [x] Entender o conceito de "Code Smells" (Mau Cheiro no Código).
- [x] Compreender por que o software se torna rígido e frágil.
- [x] Introduzir a necessidade dos Padrões de Projeto.
💡 O software apodrece?
Sim, se não for bem cuidado. Esse processo é chamado de Erosão Arquitetural. Os principais sintomas são:
- Rigidez: Difícil de mudar.
- Fragilidade: Muda aqui, quebra lá.
- Imobilidade: Não dá para reaproveitar partes do código.
- Viscosidade: Fazer o certo é mais difícil do que fazer o "atalho".
🧱 Exemplos de Code Smells
- Código Duplicado: A mesma lógica em vários lugares.
- Método Longo: Funções com centenas de linhas.
- Classe Grande: Classes que tentam ser o sistema inteiro.
- Inveja de Escopo: Uma classe que se interessa mais pelos dados de outra do que pelos seus.
📊 Ciclo de Vida do Débito Técnico
graph TD
A[Pressão por Prazo] --> B[Atalho no Código]
B --> C[Aumento do Débito Técnico]
C --> D[Dificuldade de Manutenção]
D --> E[Mais Pressão]
E --> A
💻 Exemplo: Código Rígido (If/Else Infinitos)
def calcular_desconto(tipo_cliente, valor):
if tipo_cliente == "GOLD":
return valor * 0.9
elif tipo_cliente == "SILVER":
return valor * 0.95
# Se surgir um novo tipo, temos que ALTERAR esta função (Violando OCP)
return valor
🧠 Destaques
Conceito: Débito Técnico
É como um empréstimo: você ganha velocidade agora, mas terá que pagar com juros (tempo de manutenção) depois.
Dica
Sempre deixe o código um pouco mais limpo do que você o encontrou (Regra do Escoteiro).
🚀 Mini-projeto: Auditoria de Código
Analise um código fornecido e liste pelo menos 5 "code smells", sugerindo como poderiam ser evitados com os princípios aprendidos na aula anterior.
🎯 Próximos Passos
-
Slides
-
Quiz
-
Exercícios
-
Projeto
Módulo 3 – Padrões Criacionais
Aula 09: Introdução aos Padrões de Projeto 📖
🎯 Objetivos da Aula
- [x] Compreender o que são Design Patterns (Padrões de Projeto).
- [x] Conhecer a origem dos padrões no livro "Gang of Four" (GoF).
- [x] Identificar as três grandes categorias: Criacionais, Estruturais e Comportamentais.
- [x] Entender os benefícios (e riscos) de usar padrões.
💡 O que são Padrões de Projeto?
Padrões de Projeto são soluções reutilizáveis para problemas comuns que ocorrem durante o design de software. Eles não são bibliotecas ou frameworks, mas sim estratégias e modelos de organização de classes e objetos.
"Não reinvente a roda. Use uma roda que já foi testada e aprovada."
📚 A Origem: Gang of Four
Em 1994, Erich Gamma, Richard Helm, Ralph Johnson e John Vlissides publicaram o livro "Design Patterns: Elements of Reusable Object-Oriented Software". Eles catalogaram 23 padrões fundamentais divididos em:
- Criacionais: Como os objetos são criados.
- Estruturais: Como classes e objetos são compostos.
- Comportamentais: Como os objetos interagem e distribuem responsabilidades.
📊 Categorias de Padrões
mindmap
root((Padrões GoF))
Criacionais
Singleton
Factory Method
Abstract Factory
Builder
Prototype
Estruturais
Adapter
Composite
Proxy
Facade
Decorator
Comportamentais
Strategy
Observer
Command
State
Template Method
💻 Por que usar? (Vantagens)
- Linguagem Comum: "Use um Singleton aqui" é mais rápido do que explicar toda a lógica.
- Robustez: Soluções testadas por milhares de desenvolvedores.
- Flexibilidade: Facilita a manutenção e evolução do sistema.
🧠 Blocos de Destaque
O Perigo: Overengineering
Usar padrões onde não são necessários torna o código complexo sem benefício. Padrões devem ser aplicados para resolver problemas, não para "parecer inteligente".
Dica de Estudo
Foque em entender o problema que o padrão resolve antes de decorar a solução.
🚀 Mini-projeto: Catálogo de Problemas
Identifique 3 problemas comuns que você já enfrentou codificando e tente adivinhar (ou pesquisar) qual categoria de padrão poderia resolvê-los.
🎯 Próximos Passos
-
Slides
-
Quiz
-
Exercícios
-
Projeto
Aula 10: Padrões Criacionais 🏭
🎯 Objetivos da Aula
- [x] Aprender os padrões Singleton, Factory Method e Builder.
- [x] Compreender quando impedir a criação de múltiplas instâncias.
- [x] Desacoplar a lógica de criação da lógica de negócio.
- [x] Construir objetos complexos passo a passo.
💡 O que são Padrões Criacionais?
Eles abstraem o processo de instanciação. Eles ajudam a tornar um sistema independente de como seus objetos são criados, compostos e representados.
🧱 Os Grandes Destaques
1. Singleton 👤
Garante que uma classe tenha apenas uma instância e fornece um ponto global de acesso a ela. Exemplo: Conexão com Banco de Dados, Log.
2. Factory Method 🏗️
Define uma interface para criar um objeto, mas deixa as subclasses decidirem qual classe instanciar.
3. Builder 👷
Separa a construção de um objeto complexo da sua representação, permitindo que o mesmo processo de construção crie diferentes representações.
📊 Diagrama: Factory Method
classDiagram
class Creator {
+createProduct()* Product
}
class ConcreteCreator {
+createProduct() Product
}
class Product {
<<interface>>
}
class ConcreteProduct {
}
Creator <|-- ConcreteCreator
Product <|-- ConcreteProduct
ConcreteCreator ..> ConcreteProduct
💻 Exemplo: Singleton em Python
class DatabaseConnection:
_instance = None
def __new__(cls):
if cls._instance is None:
cls._instance = super(DatabaseConnection, cls).__new__(cls)
print("Conectando ao banco...")
return cls._instance
db1 = DatabaseConnection()
db2 = DatabaseConnection()
print(f"São a mesma instância? {db1 is db2}")
🧠 Blocos de Destaque
Cuidado com o Singleton
O Singleton pode ser considerado um "anti-padrão" se usado em excesso, pois cria um estado global oculto que dificulta os testes unitários.
Builder vs Factory
Use Factory quando a criação é simples (uma linha). Use Builder quando o objeto tem muitos parâmetros opcionais ou passos de construção.
🚀 Mini-projeto: Gerador de Documentos
Crie um sistema que utiliza o padrão Factory para gerar diferentes tipos de documentos (PDF, JSON, HTML) sem que o cliente saiba qual classe específica está sendo instanciada.
🎯 Próximos Passos
-
Slides
-
Quiz
-
Exercícios
-
Projeto
Aula 11: Aplicando Padrões Criacionais em Projeto 🛠️
🎯 Objetivos da Aula
- [x] Praticar a escolha do padrão criacional adequado.
- [x] Refatorar código acoplado usando Abstract Factory.
- [x] Implementar o padrão Builder para objetos altamente configuráveis.
- [x] Identificar padrões criacionais em bibliotecas famosas.
💡 O Caso: Criador de Avatares (RPG)
Imagine um sistema de criação de personagens onde temos: - Raças (Humano, Elfo, Orc) - Classes (Guerreiro, Mago, Arqueiro) - Equipamentos (Espada, Cajado, Arco)
Tentar criar tudo isso com if/else e instanciando classes diretamente gera um código frágil e difícil de expandir.
📊 Estratégia de Refatoração
graph LR
Client[Interface do Usuário] --> Director[PersonagemDirector]
Director --> Builder[PersonagemBuilder]
Builder --> Product[Personagem Final]
💻 Exemplo: Padrão Builder (Python)
class Personagem:
def __init__(self):
self.nome = None
self.arma = None
self.armadura = None
class PersonagemBuilder:
def __init__(self):
self.p = Personagem()
def set_nome(self, nome):
self.p.nome = nome
return self
def set_arma(self, arma):
self.p.arma = arma
return self
def build(self):
return self.p
# Uso fluente
heroi = PersonagemBuilder().set_nome("Aragon").set_arma("Andúril").build()
🧠 Blocos de Destaque
Abstract Factory
É uma "fábrica de fábricas". Use-a quando precisar criar famílias de objetos relacionados (ex: Kit UI Dark vs Kit UI Light) sem especificar suas classes concretas.
Dica de Implementação
Muitas vezes o Singleton e o Abstract Factory trabalham juntos, onde a fábrica em si é um Singleton.
🚀 Mini-projeto: Fábrica de Temas de Interface
Desenvolva um sistema que, baseado em uma configuração, entrega um conjunto de Botões e Menus (Dark ou Light) usando Abstract Factory.
🎯 Próximos Passos
-
Slides
-
Quiz
-
Exercícios
-
Projeto
Módulo 4 – Estruturais e Comportamentais
Aula 12: Padrões Estruturais 🔗
🎯 Objetivos da Aula
- [x] Conhecer os padrões Adapter, Composite, Decorator e Facade.
- [x] Aprender a harmonizar interfaces incompatíveis.
- [x] Representar hierarquias de objetos "parte-todo".
- [x] Adicionar responsabilidades a objetos dinamicamente.
💡 O que são Padrões Estruturais?
Eles lidam com a composição de classes e objetos para formar estruturas maiores e mais complexas. Eles ajudam a garantir que, quando uma parte muda, a estrutura inteira não precise ser alterada.
🧱 Destaques Estruturais
1. Adapter (Adaptador) 🔌
Converte a interface de uma classe em outra interface que os clientes esperam. Exemplo: Conectar um sistema novo em um banco de dados legado.
2. Composite (Composição) 🌳
Compõe objetos em estruturas de árvore para representar hierarquias. Permite tratar objetos individuais e composições de forma uniforme.
3. Decorator (Decorador) 🎀
Adiciona comportamento a um objeto individual, estaticamente ou dinamicamente, sem afetar o comportamento de outros objetos da mesma classe.
📊 Diagrama: Adapter
graph LR
Client[Cliente] --> ITarget[Interface Alvo]
ITarget --> Adapter[Adapter]
Adapter --> Adaptee[Sistema Legado]
💻 Exemplo: Decorator em Python
class Cafe:
def custo(self):
return 5
class LeiteDecorator:
def __init__(self, cafe):
self._cafe = cafe
def custo(self):
return self._cafe.custo() + 2
meu_cafe = Cafe()
meu_cafe_com_leite = LeiteDecorator(meu_cafe)
print(f"Custo total: {meu_cafe_com_leite.custo()}")
🧠 Blocos de Destaque
Facade (Fachada)
Fornece uma interface simplificada para um conjunto complexo de classes em um subsistema. É como o painel de um carro: você vira a chave (facade) e muitos sistemas complexos funcionam por trás sem você ver.
Proxy
Atua como um substituto ou porta-voz de outro objeto para controlar o acesso a ele.
🚀 Mini-projeto: Sistema de Arquivos
Use o padrão Composite para criar uma estrutura de Pastas e Arquivos, onde uma Pasta pode conter tanto Arquivos quanto outras Pastas, e todos podem ser "listados" da mesma forma.
🎯 Próximos Passos
-
Slides
-
Quiz
-
Exercícios
-
Projeto
Aula 13: Padrões Comportamentais 🧠
🎯 Objetivos da Aula
- [x] Compreender os padrões Strategy, Observer, Command e Template Method.
- [x] Aprender a encapsular algoritmos trocáveis.
- [x] Implementar comunicação de "um-para-muitos" desacoplada.
- [x] Padronizar passos de um algoritmo mantendo partes flexíveis.
💡 O que são Padrões Comportamentais?
Eles se preocupam com algoritmos e a atribuição de responsabilidades entre objetos. Eles não descrevem apenas padrões de objetos ou classes, mas também os padrões de comunicação entre eles.
🧱 Destaques Comportamentais
1. Strategy (Estratégia) 🎯
Define uma família de algoritmos, encapsula cada um deles e os torna intercambiáveis em tempo de execução. Exemplo: Diferentes formas de cálculo de frete ou desconto.
2. Observer (Observador) 🔔
Define uma dependência um-para-muitos entre objetos, de modo que quando um objeto muda de estado, todos os seus dependentes são notificados. Exemplo: Newsletter, Notificações de ações na bolsa.
3. Template Method 📝
Define o esqueleto de um algoritmo em uma operação, deixando alguns passos para as subclasses.
📊 Sequência: Observer
sequenceDiagram
participant S as Assunto (Subject)
participant O1 as Observador A
participant O2 as Observador B
S->>O1: Notificar Mudança
S->>O2: Notificar Mudança
O1->>S: Reagir/Atualizar
O2->>S: Reagir/Atualizar
💻 Exemplo: Strategy em Python
class FreteEstrategia:
def calcular(self, valor): pass
class FreteExpresso(FreteEstrategia):
def calcular(self, valor): return valor * 0.1
class FreteNormal(FreteEstrategia):
def calcular(self, valor): return valor * 0.05
class CalculadoraDeFrete:
def calcular(self, valor, estrategia):
return estrategia.calcular(valor)
calc = CalculadoraDeFrete()
print(calc.calcular(100, FreteExpresso()))
🧠 Blocos de Destaque
Command
Encapsula uma solicitação como um objeto, permitindo parametrizar clientes com diferentes solicitações e suportar operações que podem ser desfeitas (Undo).
Dica
O padrão Strategy ajuda a eliminar grandes blocos de if/else ou switch relacionados a regras de negócio que mudam frequentemente.
🚀 Mini-projeto: Sistema de Eventos
Implemente o padrão Observer para um sistema de notícias onde múltiplos assinantes (E-mail, SMS, Webhook) recebem atualizações quando uma nova notícia é publicada.
🎯 Próximos Passos
-
Slides
-
Quiz
-
Exercícios
-
Projeto
Aula 14: MVC e Arquitetura 🏛️
🎯 Objetivos da Aula
- [x] Compreender o padrão arquitetural MVC (Model-View-Controller).
- [x] Aprender a separar lógica de negócio, interface e controle.
- [x] Ver a aplicação do MVC em sistemas modernos (Web e Desktop).
- [x] Identificar os padrões GoF que compõem o MVC.
💡 O que é MVC?
O MVC é um padrão de arquitetura de software que divide a aplicação em três componentes interconectados, cada um com uma responsabilidade específica:
- Model (Modelo): Gerencia os dados, a lógica de negócio e as regras de persistência.
- View (Visão): Responsável pela apresentação visual dos dados ao usuário.
- Controller (Controle): Atua como intermediário, recebendo a entrada do usuário e coordenando as ações entre o Model e a View.
📊 Fluxo MVC
graph LR
User[Usuário] -->|Interação| C[Controller]
C -->|Atualiza| M[Model]
M -->|Notifica| V[View]
V -->|Mostra| User
🧱 Padrões por Trás do MVC
O MVC não é um padrão único, mas uma combinação de vários: - Observer: O Model notifica a View sobre mudanças. - Strategy: O Controller define como a View reage às entradas. - Composite: A View costuma ser uma estrutura composta de widgets.
👨💻 Exemplo Conceitual (Python Simplificado)
class Model:
def __init__(self):
self.dados = "Olá MVC"
class View:
def exibir(self, model):
print(f"Tela: {model.dados}")
class Controller:
def __init__(self, model, view):
self.model = model
self.view = view
def mudar_dados(self, novo_texto):
self.model.dados = novo_texto
self.view.exibir(self.model)
# Execução
app = Controller(Model(), View())
app.mudar_dados("Nova Mensagem")
🧠 Blocos de Destaque
MVC na Web
Em frameworks web modernos (como Django, Spring MVC, Rails), o MVC é ligeiramente adaptado, onde a View é frequentemente o HTML/Template e o Model é a camada de dados (ORM).
Benefício
A principal vantagem do MVC é o desacoplamento. Você pode trocar a interface (View) sem precisar mexer na lógica de negócio (Model).
🚀 Mini-projeto: Task Manager MVC
Vamos esboçar a estrutura de um gerenciador de tarefas simples, separando as classes em pastas model/, view/ e controller/.
🎯 Próximos Passos
-
Slides
-
Quiz
-
Exercícios
-
Projeto
Aula 15: Refatoração com Padrões ♻️
🎯 Objetivos da Aula
- [x] Identificar oportunidades de melhoria em código legado.
- [x] Substituir condicionais complexas por polimorfismo (Strategy).
- [x] Desacoplar sistemas usando Adapter.
- [x] Aplicar o ciclo: Identificar cheiro -> Escolher Padrão -> Refatorar.
💡 O Poder da Refatoração
Refatorar não é apenas "mudar o nome de variáveis". É alterar a estrutura interna do código para torná-lo mais elegante e sustentável, sem alterar seu comportamento externo.
"Se o código está funcionando, mas é um pesadelo de manter, ele está quebrado conceitualmente."
📊 De Switch para Strategy
graph TD
Old[Switch Case Gigante] --> Refactor[Refatoração]
Refactor --> New[Classes de Estratégia]
New --> Result[Código Flexível e OCP]
💻 Caso Real: Processamento de Pagamentos
Antes (Problemático)
def processar(tipo, valor):
if tipo == "CC": # Cartão de Crédito
# Lógica CC
elif tipo == "PIX":
# Lógica PIX
# Difícil de expandir!
Depois (Refatorado com Padrões)
class Pagamento:
def pagar(self, valor): pass
# Agora cada novo método é uma nova CLASSE, não um novo IF.
class PagamentoPix(Pagamento):
def pagar(self, valor):
print(f"Pagando R$ {valor} via Pix")
🧠 Destaques
Regra de Ouro
Antes de refatorar, garanta que você tenha testes automatizados. Eles são sua rede de proteção para garantir que você não quebrou nada durante a limpeza.
Atenção
Cuidado para não "sobrerrefatorar". Às vezes, um if simples é melhor do que 10 classes de padrão complexo. Use o bom senso.
🚀 Mini-projeto: Limpando o Legado
Pegue o seu projeto da Aula 08 (onde você auditou code smells) e agora aplique os padrões aprendidos para resolver pelo menos dois dos problemas identificados.
🎯 Próximos Passos
-
Slides
-
Quiz
-
Exercícios
-
Projeto
Módulo 5 – Projeto Final
Aula 16: Desenvolvimento de Mini Projeto 🏆
🎯 Objetivos da Aula
- [x] Aplicar os conhecimentos adquiridos em um cenário real.
- [x] Escolher o paradigma mais adequado para diferentes partes do sistema.
- [x] Implementar pelo menos 2 padrões de projeto (GoF).
- [x] Demonstrar princípios de Clean Code e SOLID.
🚀 O Desafio Final
Você deve desenvolver um protótipo funcional (focado na arquitetura) de um dos seguintes sistemas:
- 🛒 Sistema de E-commerce: Com cálculo de frete (Strategy), catálogo (Composite) e log de transações (Singleton).
- 🚗 Gestão de Frota/Logística: Com rastreamento (Observer), criação de veículos (Factory/Builder) e interface simplificada (Facade).
📋 Requisitos Obrigatórios
- Modularidade: O sistema deve estar dividido em camadas (MVC ou similar).
- Padrões: Implementação clara de no mínimo 2 Design Patterns.
- Paradigma: Uso de POO para a estrutura e pelo menos um trecho usando técnicas Funcionais (Map/Filter).
- Documentação: Um breve arquivo
README.mdexplicando as decisões arquiteturais tomadas.
📊 Arquitetura Sugerida
graph TD
UI[Interface/CLI] --> C[Controller]
C --> M[Model / Negócio]
M --> P1[Padrão Criacional]
M --> P2[Padrão Comportamental]
M --> DB[(Simulador DB)]
💻 Exemplo de Estrutura de Pastas
# Estrutura recomendada para o projeto
mkdir meu_projeto
cd meu_projeto
mkdir src tests docs
touch src/main.py src/models.py src/patterns.py
🧠 Dica para a Apresentação
Foco Técnico
Não se preocupe com uma interface gráfica bonita. O foco aqui é o "Motor" do sistema. Explique por que você escolheu o padrão X em vez do Y.
Critério de Sucesso
O código deve ser fácil de ler, testar e, acima de tudo, fácil de estender para novas funcionalidades.
🏁 Encerramento do Curso
Parabéns por chegar até aqui! Você agora possui uma base sólida em design de software que o acompanhará por toda a sua carreira.
🎯 Próximos Passos
-
Certificação
-
Materiais de Apoio
Materiais
Materiais Complementares 📚
Bem-vindo à seção de materiais complementares do curso de Paradigmas de Programação e Padrões de Projeto. Aqui você encontra recursos adicionais para apoiar seus estudos e aprofundar seu conhecimento técnico.
-
Slides --- Acompanhe o conteúdo teórico com slides interativos e diagramas Mermaid.
-
Exercícios --- Pratique a modelagem e aplicação de paradigmas e padrões de projeto.
-
Quizzes --- Valide seu aprendizado com testes rápidos para cada uma das 16 aulas.
-
Projetos --- Desenvolva soluções arquitetadas seguindo padrões da indústria.
-
Ambiente --- Guias de configuração de ambiente (Java, Python, JS e Ferramentas CASE).
Galeria de Slides 📊
Acesse os slides interativos de cada aula.
Exercícios do Curso 🏋️
Lista de exercícios progressivos para cada aula.
Ambientes de Desenvolvimento 🛠️
Guias para configurar seu computador para o desenvolvimento mobile.
-
Android --- Instalação do Android Studio, SDK e emuladores.
-
iOS (Opcional/Referência) --- Configuração básica de Xcode e ferramentas Mac.
-
Ferramentas de Apoio --- Git, Terminais e Postman/Insomnia para testes de API.
Versão para Impressão
Esta página foi gerada automaticamente para impressão.