Semana 3: JavaScript Profissional

Programação Orientada a Objetos, Design Patterns e Performance

🎯 Objetivo: Dominar conceitos avançados de JavaScript para desenvolvimento profissional

📊 Seu Progresso

0% concluído

1

Nível Básico

Classes e Programação Orientada a Objetos

🏗️ Classes ES6

Classes são como "moldes" para criar objetos. É uma forma organizada de agrupar dados (propriedades) e ações (métodos) relacionados!

📝 Exemplo Prático:

// Criando uma classe Pessoa
class Pessoa {
    // Constructor: executa quando criamos uma nova pessoa
    constructor(nome, idade) {
        this.nome = nome;
        this.idade = idade;
        this.energia = 100;
    }
    
    // Método para a pessoa se apresentar
    apresentar() {
        return `Olá! Eu sou ${this.nome} e tenho ${this.idade} anos.`;
    }
    
    // Método para fazer exercício
    exercitar() {
        this.energia -= 20;
        return `${this.nome} fez exercício! Energia: ${this.energia}`;
    }
    
    // Método para descansar
    descansar() {
        this.energia = Math.min(100, this.energia + 30);
        return `${this.nome} descansou! Energia: ${this.energia}`;
    }
}

// Criando objetos da classe
const pessoa1 = new Pessoa('Ana', 25);
const pessoa2 = new Pessoa('João', 30);

console.log(pessoa1.apresentar());
console.log(pessoa1.exercitar());
console.log(pessoa1.descansar());

📤 Demonstração:

👤 Ana (25 anos)
Energia:
100

                    

🧬 Herança

Herança permite criar classes "filhas" que herdam características da classe "pai", mas podem ter suas próprias funcionalidades especiais!

// Classe pai (base)
class Animal {
    constructor(nome, tipo) {
        this.nome = nome;
        this.tipo = tipo;
        this.felicidade = 50;
    }
    
    comer() {
        this.felicidade += 10;
        return `${this.nome} comeu e está mais feliz! 😊`;
    }
    
    dormir() {
        this.felicidade += 5;
        return `${this.nome} dormiu bem! 😴`;
    }
}

// Classe filha que herda de Animal
class Cachorro extends Animal {
    constructor(nome, raca) {
        super(nome, 'Cachorro'); // Chama o constructor do pai
        this.raca = raca;
        this.latidos = 0;
    }
    
    // Método específico do cachorro
    latir() {
        this.latidos++;
        return `${this.nome} fez: Au au! 🐕 (${this.latidos}x)`;
    }
    
    // Sobrescrevendo método do pai
    comer() {
        this.felicidade += 15; // Cachorros ficam mais felizes comendo
        return `${this.nome} devorou a comida! 🦴`;
    }
}

// Criando um cachorro
const rex = new Cachorro('Rex', 'Golden Retriever');
console.log(rex.latir());
console.log(rex.comer());
console.log(`Felicidade: ${rex.felicidade}`);

📤 Demonstração:

🐕 Rex (Golden Retriever)
Felicidade:
50
Latidos: 0

                    

🎯 Exercício: Criando uma Classe Carro

Crie uma classe Carro com propriedades e métodos:

🚗 Demonstração do Carro
Modelo: -
Velocidade: 0 km/h
Combustível: 100%

Tarefa: Complete a classe Carro com os métodos acelerar, frear e abastecer.

2

Nível Intermediário

Módulos ES6 e Design Patterns

📦 Módulos ES6

Módulos nos permitem organizar código em arquivos separados e reutilizar funcionalidades. É como ter uma caixa de ferramentas organizada!

// Simulando módulos (normalmente em arquivos separados)

// 📁 matematica.js (módulo)
const Matematica = {
    // Exportando funções
    somar: (a, b) => a + b,
    
    multiplicar: (a, b) => a * b,
    
    calcularArea: (largura, altura) => largura * altura,
    
    // Constante exportada
    PI: 3.14159
};

// 📁 utilidades.js (módulo)
const Utilidades = {
    formatarMoeda: (valor) => {
        return `R$ ${valor.toFixed(2).replace('.', ',')}`;
    },
    
    formatarData: (data) => {
        return data.toLocaleDateString('pt-BR');
    },
    
    gerarId: () => {
        return Math.random().toString(36).substr(2, 9);
    }
};

// 📁 main.js (arquivo principal)
// Usando os módulos
const resultado = Matematica.somar(10, 5);
const area = Matematica.calcularArea(4, 3);
const preco = Utilidades.formatarMoeda(29.99);
const id = Utilidades.gerarId();

console.log(`Soma: ${resultado}`);
console.log(`Área: ${area}`);
console.log(`Preço: ${preco}`);
console.log(`ID gerado: ${id}`);

📤 Demonstração:

📦 Módulo Matemática
🛠️ Módulo Utilidades

                    

🎨 Design Patterns

Design Patterns são soluções testadas para problemas comuns na programação. É como ter receitas prontas para situações específicas!

// 🏭 Factory Pattern - Fábrica de objetos
class FabricaVeiculos {
    static criarVeiculo(tipo, modelo) {
        switch(tipo) {
            case 'carro':
                return {
                    tipo: 'Carro',
                    modelo: modelo,
                    rodas: 4,
                    acelerar: () => 'Carro acelerando! 🚗'
                };
            case 'moto':
                return {
                    tipo: 'Moto',
                    modelo: modelo,
                    rodas: 2,
                    acelerar: () => 'Moto acelerando! 🏍️'
                };
            case 'bicicleta':
                return {
                    tipo: 'Bicicleta',
                    modelo: modelo,
                    rodas: 2,
                    acelerar: () => 'Pedalando! 🚲'
                };
            default:
                throw new Error('Tipo de veículo não suportado');
        }
    }
}

// 👁️ Observer Pattern - Observador
class EventoManager {
    constructor() {
        this.observadores = [];
    }
    
    adicionarObservador(callback) {
        this.observadores.push(callback);
    }
    
    notificar(evento) {
        this.observadores.forEach(obs => obs(evento));
    }
}

// Usando os patterns
const carro = FabricaVeiculos.criarVeiculo('carro', 'Civic');
const eventos = new EventoManager();

eventos.adicionarObservador(evento => 
    console.log(`📢 Notificação: ${evento}`)
);

eventos.notificar('Novo veículo criado!');
console.log(carro.acelerar());

📤 Demonstração:

🏭 Factory Pattern
👁️ Observer Pattern
Observadores: 0

                    

🎯 Exercício: Sistema de Notificações

Implemente um sistema de notificações usando Observer Pattern:

📱 Central de Notificações

Tarefa: Complete o sistema de notificações.

3

Nível Avançado

Performance, Debugging e Error Handling

⚡ Performance e Otimização

Performance é sobre fazer seu código rodar mais rápido e usar menos recursos. Vamos ver técnicas para otimizar nosso JavaScript!

// 🐌 Código lento vs ⚡ Código otimizado

// Exemplo 1: Debounce - evita execuções excessivas
function debounce(func, delay) {
    let timeoutId;
    return function(...args) {
        clearTimeout(timeoutId);
        timeoutId = setTimeout(() => func.apply(this, args), delay);
    };
}

// Exemplo 2: Memoização - cache de resultados
function memoize(fn) {
    const cache = new Map();
    return function(...args) {
        const key = JSON.stringify(args);
        if (cache.has(key)) {
            console.log('📋 Resultado do cache!');
            return cache.get(key);
        }
        console.log('🔄 Calculando...');
        const result = fn.apply(this, args);
        cache.set(key, result);
        return result;
    };
}

// Função pesada para demonstrar memoização
const fibonacci = memoize(function(n) {
    if (n <= 1) return n;
    return fibonacci(n - 1) + fibonacci(n - 2);
});

// Exemplo 3: Medindo performance
function medirTempo(nome, funcao) {
    const inicio = performance.now();
    const resultado = funcao();
    const fim = performance.now();
    console.log(`⏱️ ${nome}: ${(fim - inicio).toFixed(2)}ms`);
    return resultado;
}

// Testando performance
const resultado1 = medirTempo('Fibonacci(30)', () => fibonacci(30));
const resultado2 = medirTempo('Fibonacci(30) - Cache', () => fibonacci(30));

📤 Demonstração:

⚡ Teste de Performance
📊 Métricas
Último tempo: -
Cache hits: 0
Execuções debounce: 0

                    

🛡️ Error Handling e Debugging

Tratar erros adequadamente torna nosso código mais robusto e confiável. Vamos aprender a capturar e lidar com erros!

// 🛡️ Try/Catch para capturar erros
function operacaoSegura(operacao) {
    try {
        console.log('🔄 Executando operação...');
        const resultado = operacao();
        console.log('✅ Operação bem-sucedida!');
        return { sucesso: true, resultado };
    } catch (error) {
        console.error('❌ Erro capturado:', error.message);
        return { sucesso: false, erro: error.message };
    } finally {
        console.log('🏁 Operação finalizada.');
    }
}

// 🎯 Criando erros customizados
class ErroCustomizado extends Error {
    constructor(message, codigo) {
        super(message);
        this.name = 'ErroCustomizado';
        this.codigo = codigo;
    }
}

// 🔍 Função para validar dados
function validarUsuario(usuario) {
    if (!usuario) {
        throw new ErroCustomizado('Usuário não fornecido', 'USER_MISSING');
    }
    if (!usuario.email) {
        throw new ErroCustomizado('Email é obrigatório', 'EMAIL_MISSING');
    }
    if (usuario.idade < 0) {
        throw new ErroCustomizado('Idade inválida', 'INVALID_AGE');
    }
    return true;
}

// 📊 Logger para debugging
const Logger = {
    info: (msg) => console.log(`ℹ️ INFO: ${msg}`),
    warn: (msg) => console.warn(`⚠️ WARN: ${msg}`),
    error: (msg) => console.error(`❌ ERROR: ${msg}`),
    debug: (msg) => console.log(`🐛 DEBUG: ${msg}`)
};

// Testando error handling
const resultado = operacaoSegura(() => {
    const usuario = { nome: 'Ana', idade: 25 }; // Email faltando
    validarUsuario(usuario);
    return 'Usuário válido!';
});

📤 Demonstração:

🛡️ Teste de Erros
📊 Status
Último teste: -
Erros capturados: 0
Sucessos: 0

                    
💻

Console Avançado

Teste conceitos avançados de JavaScript!

// Saída aparecerá aqui...
🏆

Desafios Finais

Teste seus conhecimentos avançados!

🎯 Desafio 1: Sistema de Tarefas OOP

Crie um sistema de gerenciamento de tarefas usando classes e herança.

🎯 Desafio 2: Cache Inteligente

Implemente um sistema de cache com expiração usando conceitos avançados.

Cache vazio
function comerRex() { if (cachorroRex) { const resultado = cachorroRex.comer(); document.getElementById('outputHeranca').textContent += resultado + '\n