voltar aos artigosadvanced topics
$cd~/artigos/design-patterns-javascript-padroes-projeto
Advanced Topics
série 33 Conceitos JS·parte 37 de 38

Design Patterns: Os Modelos de Solução que Todo Dev Precisa Conhecer

24 minVanderlei José Alamino

"Não reinvente a roda. Aprenda a usar as ferramentas certas para cada problema." — adaptado de Christopher Alexander

Design patterns são soluções testadas para problemas recorrentes — não código para copiar, mas plantas que você adapta. A Gang of Four catalogou 23 padrões em 1994; em JavaScript moderno, muitos simplificam ou viram desnecessários.

snippetJavaScript
export function createUser(type, name) {  switch (type) {    case 'admin': return { name, role: 'admin', permissions: ['read', 'write', 'delete'] };    default: return { name, role: 'viewer', permissions: ['read'] };  }}

Neste guia da série 33 Conceitos JS — projeto open source criado por Leonardo Maldonado — você aprende seis padrões úteis no JS: Module, Singleton, Factory, Observer, Proxy e Decorator.

Pré-requisitos: ES Modules, Factories & Classes e Higher-Order Functions.

design-patterns-javascript-padroes-projeto.meta.jsonjson

// metadados do artigo

{
  "tag": "advanced topics",
  "readTime": "24 min",
  "author": "Vanderlei José Alamino",
  "source": "33jsconcepts.com",
  "series": "33 Conceitos JS",
  "part": {
    "current": 37,
    "total": 38
  }
}
abrir fonte original
design-patterns-javascript-padroes-projeto.mdmarkdown

Fonte de referência

Conteúdo adaptado a partir do guia original em inglês.

33jsconcepts.com
01

seção

Analogia: A Oficina Mecânica

Cada ferramenta resolve um problema recorrente — você não inventa um macaco novo para cada pneu.

Patterns são a caixa de ferramentas do software: Module, Factory, Observer… escolha pela necessidade, não pelo hype.

02

seção

O que são Design Patterns?

Soluções típicas catalogadas pela Gang of Four (1994) — 23 padrões em C++/Smalltalk.

JS modernoImpacto
Funções de 1ª classePatterns viram funções simples
ClosuresEstado privado natural
ES ModulesSubstitui Module Pattern manual
Herança prototipalMenos hierarquias de classe

Categorias GoF: Creational (criação), Structural (composição), Behavioral (comunicação) + Module (idioma JS).

03

seção

Module Pattern

Encapsula código com API pública e estado privado.

ES Modules (moderno):

snippetJavaScript
let count = 0;export function increment() { return ++count; }export function getCount() { return count; }

IIFE clássico (legado):

snippetJavaScript
const Counter = (function () {  let count = 0;  return {    increment() { return ++count; },    getCount() { return count; },  };})();

Projetos novos → ES Modules. Legado → IIFE & Namespaces.

04

seção

Singleton Pattern

Uma instância global — em JS, módulos ES já são singletons:

snippetJavaScript
export const config = { apiUrl: 'https://api.example.com' };// todo import recebe o mesmo objeto
snippetJavaScript
Object.freeze({ apiUrl: '...', debug: false });  // config imutável

Problemas: testes compartilham estado, dependências ocultas, acoplamento.

Quando faz sentido: logger global, config congelada, connection pool — com parcimônia.

05

seção

Factory Pattern

Cria objetos sem expor lógica de criação ao caller:

snippetJavaScript
function createUser(type, name) {  const base = { name, greet() { return `Hi, I'm ${this.name}`; } };  switch (type) {    case 'admin': return { ...base, role: 'admin', permissions: ['read', 'write', 'delete'] };    case 'editor': return { ...base, role: 'editor', permissions: ['read', 'write'] };    default: return { ...base, role: 'viewer', permissions: ['read'] };  }}

Use quando: setup complexo, tipos dinâmicos por input, desacoplar criação do uso.

Aprofunde em Factories & Classes.

06

seção

Observer Pattern

Publisher notifica subscribers — base de DOM events, React state, EventEmitter, RxJS.

snippetJavaScript
class Observable {  constructor() { this.observers = []; }  subscribe(fn) {    this.observers.push(fn);    return () => { this.observers = this.observers.filter(o => o !== fn); };  }  notify(data) { this.observers.forEach(fn => fn(data)); }}

Três partes: lista de observers, subscribe (com unsubscribe), notify.

FormField observável valida email e conta caracteres no mesmo setValue.

07

seção

Proxy Pattern

Intercepta operações em objetos — validação, logging, lazy loading:

snippetJavaScript
const userProxy = new Proxy(user, {  get(target, prop) { return target[prop]; },  set(target, prop, value) {    if (prop === 'age' && value < 0) throw new Error('Age inválida');    target[prop] = value;    return true;  },});

Lazy loading: cria recurso caro só no primeiro acesso via trap get.

Proxy controla acesso; Decorator adiciona comportamento.

08

seção

Decorator Pattern

Envolve objeto/função para adicionar capacidades sem modificar o original:

snippetJavaScript
const withFlying = (c) => ({ ...c, fly() { return `${c.name} voa!`; } });const duck = withFlying(createCharacter('Duck'));

Decorators de função — logging, memoization:

snippetJavaScript
const withMemo = (fn) => {  const cache = new Map();  return (...args) => {    const key = JSON.stringify(args);    if (cache.has(key)) return cache.get(key);    const result = fn(...args);    cache.set(key, result);    return result;  };};

Relacionado a Currying & Composition e HOFs.

09

seção

Erros Comuns

  1. Over-engineering — Factory para { name: 'Alice' } simples
  2. Pattern errado — Singleton quando export de módulo basta
  3. Ignorar idiomas JS — closures e modules resolvem metade dos casos
  4. Abstração prematura — YAGNI vale para patterns

Martelo de ouro: usar o pattern que você acabou de aprender em todo lugar.

Pergunte: problema real? solução mais simples? JS já resolve? equipe entende?

10

seção

Escolhendo o Pattern

ProblemaPatternAlternativa JS
Estado privado + APIModuleES import/export
Uma instânciaSingletonexport const x = {}
Criação dinâmicaFactoryfunção retornando objeto
Múltiplos listenersObservercallback, EventEmitter
Validar/acessarProxygetters/setters
Comportamento extraDecoratorHOF, composição

Regra de ouro: comece simples; introduza pattern quando o problema aparecer.

11

seção

Perguntas Clássicas de Entrevista

12

seção

Teste Seu Conhecimento

$ summary --quick

Resumo rápido

  • Patterns = templates — adapte, não copie cegamente
  • JS simplifica GoF — funções, closures, modules
  • Module — ES modules em projetos novos
  • Singleton — módulos ES já cacheiam; use com cuidado
  • Factory — criação centralizada por tipo/input
  • Observer — subscribe + notify; base de eventos
  • Proxy — intercepta get/set; validação, lazy load
  • Decorator — wrap para logging, cache, features
  • YAGNI — código simples > pattern engenhoso
  • DOM, Promises, middleware — patterns no mundo real

Créditos da série

Este artigo faz parte de uma série de estudos inspirada no projeto 33 Conceitos JS, criado por Leonardo Maldonado. Todo o conteúdo original está disponível em 33jsconcepts.com.