UC04372

Programar com código generativo

Programação genérica, geração de código, design patterns e metaprogramação, aplicados a conteúdos interativos

Curso profissional · 25h · Técnico de Produção de Conteúdos Interativos

Plano

  1. Programação genérica: princípios e linguagens
  2. Código generativo e meta linguagens
  3. Ferramentas e técnicas de geração de código
  4. Frameworks e templates de desenvolvimento
  5. Design patterns: conceitos e princípios
  6. Tipos de design patterns
  7. Código genérico: herança e polimorfismo
  8. Metaprogramação
  9. Tipagem dinâmica para código genérico
  10. Frameworks e bibliotecas flexíveis
  11. Adaptar código para automatizar tarefas
  12. Testar código em diferentes plataformas
  13. Segurança no código gerado
  14. Normas de segurança, saúde e ambiente
  15. Boas práticas e critérios de desempenho

Bloco 1 · Programação genérica

O que é programação genérica

A programação genérica escreve algoritmos e estruturas que funcionam com qualquer tipo de dados, sem repetir código para cada tipo.

  • Um só Stack<T> serve para números, texto ou objetos próprios.
  • Reduz duplicação: escreve-se a lógica uma vez, reutiliza-se sempre.
  • Base de linguagens como TypeScript, Java, C# e C++ (templates).
  • Critério da UC: garantir que a geração de código é escalável, sem gargalos.

Genérico não é "vago": é preciso o suficiente para compilar e específico o suficiente para reutilizar.

Tipos de linguagens de programação genérica

Categoria Exemplo Como resolve a genericidade
Estaticamente tipadas com genéricos TypeScript, Java, C# tipos verificados em compilação, com parâmetros <T>
Templates (compilação) C++ o compilador gera código específico por tipo usado
Dinamicamente tipadas JavaScript, Python genericidade "grátis": qualquer valor serve, verificado em execução

Nesta UC trabalhamos sobretudo em TypeScript: junta a segurança dos tipos ao ecossistema JavaScript da produção de conteúdos interativos.

Bloco 2 · Código generativo e meta linguagens

O que é código generativo

Código generativo é código que escreve outro código: em vez de o teres de digitar à mão, um programa, um template ou um modelo gera-o por ti.

  • Geradores clássicos: um script lê uma especificação e produz ficheiros .ts, .css, .json.
  • Metaprogramação: código que examina e modifica código, o seu ou de outros, em tempo de execução ou de compilação.
  • IA generativa de código: assistentes que geram excertos a partir de linguagem natural (GitHub Copilot, ChatGPT, Claude).
  • Em todos os casos, o objetivo é o mesmo: menos digitação repetitiva, mais consistência.

Código generativo não substitui o programador: acelera a parte mecânica para deixar tempo à parte que exige critério.

Meta linguagens

Uma meta linguagem descreve ou gera outra linguagem. É o "molde" a partir do qual sai o código final.

  • Templates de texto: Handlebars, EJS, Nunjucks misturam HTML com marcadores que o motor substitui.
  • DSL (linguagem de domínio específico): uma mini linguagem feita para um problema concreto, ex.: um ficheiro .yaml que descreve os ecrãs de um jogo.
  • Esquemas e schemas: JSON Schema, GraphQL SDL descrevem a forma dos dados e podem gerar tipos e formulários automaticamente.

Aprender a "linguagem que gera a linguagem" é o que separa quem copia e cola de quem constrói ferramentas.

Bloco 3 · Ferramentas e técnicas de geração de código

Geradores e scaffolding

Scaffolding é gerar a estrutura inicial de um projeto ou de uma peça de código, em vez de a criar à mão sempre do zero.

  • CLI de projeto: npm create vite@latest, create-react-app geram um projeto completo em segundos.
  • Geradores de componentes: Plop, Hygen criam ficheiros a partir de um template e de perguntas ao utilizador (nome do componente, tipo).
  • Geradores de API/dados: a partir de um schema, geram tipos, validações e até formulários.
  • Boa prática: gerar sempre um esqueleto consistente com o resto do projeto (nomes, pastas, testes incluídos).

Assistentes de IA generativa no código

Ferramentas como GitHub Copilot, ChatGPT e Claude geram excertos de código a partir de um pedido em linguagem natural ou do contexto do ficheiro.

  • Úteis para automatizar tarefas repetitivas: escrever testes, converter formatos, preencher funções previsíveis.
  • Não substituem a revisão humana: o código gerado pode ter erros lógicos, dependências desatualizadas ou falhas de segurança.
  • Critério de desempenho da UC: evitar estrangulamento no processo de geração, ou seja, não bloquear o trabalho à espera do gerador nem aceitar tudo sem pensar.
  • Regra da casa: ler sempre antes de aceitar; testar sempre antes de integrar.

Bloco 4 · Frameworks e templates de desenvolvimento

Frameworks com templates

Um framework dá a estrutura, as regras e as ferramentas para desenvolver mais depressa. Muitos incluem o seu próprio sistema de templates.

  • React/Vue: componentes como templates reutilizáveis, com dados a entrar por propriedades (props).
  • Angular: templates HTML com diretivas próprias (*ngFor, *ngIf) que o framework compila.
  • Motores de template server-side: EJS, Pug, Handlebars, para gerar HTML no servidor.
  • Vantagem: o framework trata da parte repetitiva (routing, ciclo de vida, atualização do ecrã); o developer foca-se na lógica.

Ferramentas com templates prontos

  • Templates de projeto (starters): repositórios prontos com configuração, testes e exemplo, para não começar do zero.
  • Bibliotecas de componentes: Material UI, shadcn/ui, com templates de botões, formulários e cartões já acessíveis.
  • Geradores de documentação: Storybook, JSDoc, geram páginas de documentação a partir de comentários no código.
  • Escolher o framework certo é uma decisão de arquitetura: pesa a curva de aprendizagem, a comunidade e a manutenção.

Bloco 5 · Design patterns: conceitos

O que são design patterns

Um design pattern (padrão de projeto) é uma solução reutilizável para um problema que se repete no desenho de software. Não é código pronto a copiar, é uma estrutura de raciocínio.

  • Documentados pela primeira vez pelo Gang of Four (1994), continuam atuais.
  • Dão vocabulário comum: dizer "isto é um Observer" poupa uma explicação inteira à equipa.
  • Ligam-se à programação genérica: muitos patterns usam tipos genéricos para funcionar com qualquer classe.
  • Critério da UC: facilitar a integração do código gerado com o resto da aplicação, um bom pattern facilita exatamente isso.

Princípios por trás dos patterns

  • DRY (Don't Repeat Yourself): não duplicar lógica, extrair para uma função, classe ou pattern.
  • SOLID: cinco princípios de desenho orientado a objetos, entre eles o Open/Closed (aberto a extensão, fechado a modificação).
  • Baixo acoplamento, alta coesão: peças que dependem pouco umas das outras e que fazem bem uma coisa.
  • Os patterns são a aplicação prática destes princípios: quando os segues com disciplina, acabas por reinventar um pattern conhecido.

Bloco 6 · Tipos de design patterns

Padrões de criação

Tratam da forma como os objetos são criados, sem expor a lógica de criação ao código que os usa.

Padrão Ideia
Factory uma função/classe decide que tipo de objeto criar
Singleton garante uma única instância partilhada (ex.: ligação à base de dados)
Builder constrói um objeto complexo passo a passo

Exemplo prático: uma ComponenteFactory que, a partir de um tipo ("video", "quiz", "galeria"), devolve o componente interativo certo, sem o código chamador saber a classe concreta.

Padrões estruturais e comportamentais

Estruturais, como as peças se compõem:

  • Adapter: adapta uma interface antiga a uma nova, sem reescrever tudo.
  • Decorator: acrescenta comportamento a um objeto sem alterar a classe original.

Comportamentais, como os objetos comunicam:

  • Observer: um objeto (sujeito) avisa vários outros (observadores) quando muda, base dos eventos e do reativo.
  • Strategy: troca o algoritmo usado em tempo de execução (ex.: diferentes formas de pontuar um quiz).

Bloco 7 · Código genérico: herança e polimorfismo

Herança

A herança permite que uma classe reutilize atributos e métodos de outra, especializando-a.

class ComponenteInterativo {
  render(): void { /* comum a todos */ }
}

class Quiz extends ComponenteInterativo {
  corrigir(resposta: string): boolean { /* específico do quiz */ return true; }
}
  • Quiz herda render() e acrescenta corrigir().
  • Reduz duplicação entre componentes parecidos.
  • Usar com cuidado: hierarquias muito profundas tornam-se difíceis de manter, "prefere composição a herança" quando o pattern o permitir.

Polimorfismo

Polimorfismo é a capacidade de tratar objetos de classes diferentes da mesma forma, através de uma interface comum.

function mostrarTodos(itens: ComponenteInterativo[]) {
  itens.forEach(i => i.render()); // cada um "sabe" o seu render()
}

mostrarTodos([new Quiz(), new Galeria()]);
  • O código chamador não precisa de saber se é Quiz ou Galeria: chama render() e cada objeto responde à sua maneira.
  • Base de bibliotecas de componentes: uma lista de "cartões interativos" pode conter tipos diferentes tratados de forma uniforme.
  • Ligado ao critério de "adaptar dinamicamente o comportamento do código".

Bloco 8 · Metaprogramação

Conceitos e princípios da metaprogramação

Metaprogramação é escrever código que examina, gera ou modifica outro código, em tempo de execução ou de compilação.

  • Reflexão: um programa consulta a sua própria estrutura (que métodos tem uma classe, que tipo tem uma variável).
  • Geração dinâmica: criar funções, classes ou objetos em tempo de execução, a partir de dados.
  • Decoradores/anotações: marcar código com metadados que outro código lê e usa (@Component, @Injectable).
  • Base de muitos frameworks: Angular, NestJS e Spring usam metaprogramação para "ligar as peças" automaticamente.

Metaprogramação em JavaScript/TypeScript

function log(target, key, descriptor) {
  const original = descriptor.value;
  descriptor.value = function (...args) {
    console.log(`A chamar ${key}`, args);
    return original.apply(this, args);
  };
}

class Quiz {
  @log
  corrigir(resposta) { /* ... */ }
}
  • O decorator @log envolve corrigir() sem alterar o seu código interno: acrescenta comportamento (registo) de fora.
  • Proxy e Reflect permitem intercetar leituras, escritas e chamadas a um objeto em tempo real.
  • Usado em bibliotecas de estado reativo (Vue 3 usa Proxy internamente para detetar alterações).

Bloco 9 · Tipagem dinâmica para código genérico

Tipagem dinâmica e duck typing

Em linguagens de tipagem dinâmica (JavaScript, Python), o tipo de uma variável só se conhece em execução. Isto dá uma genericidade "natural".

  • Duck typing: "se anda como pato e faz quack como pato, é um pato", ou seja, importa o que o objeto sabe fazer, não a classe a que pertence.
  • Vantagem: código muito flexível, funciona com qualquer objeto que tenha os métodos certos.
  • Risco: erros de tipo só aparecem em execução, às vezes em produção. Ferramentas como TypeScript e testes automáticos mitigam isto.
function tocar(objeto) {
  objeto.play(); // funciona com um vídeo, um áudio ou um jogo, desde que tenham play()
}

Armazenar e manipular dados de tipos diferentes

  • Estruturas genéricas: Array<T>, Map<K, V> guardam qualquer tipo de dados com a mesma API.
  • Union types (TypeScript): string | number descreve um valor que pode ser de mais do que um tipo.
  • Validação em fronteira: ao entrar dados externos (formulário, API), valida-se e converte-se para o tipo esperado antes de usar.
  • Isto liga-se diretamente à aptidão da UC "armazenar e manipular diferentes tipos de dados" e ao critério "validar entradas".

Bloco 10 · Frameworks e bibliotecas flexíveis

Arquitetura de frameworks flexíveis

Frameworks e bibliotecas flexíveis dão funcionalidades genéricas que se adaptam ao projeto, em vez de impor uma única forma de trabalhar.

  • Plugins e middlewares: o framework expõe "ganchos" (hooks) onde se liga código próprio, sem tocar no núcleo.
  • Configuração vs convenção: uns pedem configuração explícita (Webpack), outros seguem convenções (Next.js, ficheiros em pastas específicas).
  • Extensibilidade: bibliotecas como React permitem criar componentes e hooks próprios que se comportam como os nativos.

Um bom framework é genérico o suficiente para servir muitos projetos, e extensível o suficiente para se ajustar ao teu.

Escolher e integrar uma biblioteca

  • Critérios: manutenção ativa, documentação, tamanho do pacote, compatibilidade com o resto do projeto.
  • Instalar com gestor de pacotes (npm, pnpm), fixar versões (package-lock.json) para builds reprodutíveis.
  • Tree-shaking: usar só o que é preciso da biblioteca, para não pesar o código final.
  • Ligado ao critério de desempenho "facilitar a integração do código gerado com o restante do código da aplicação".

Bloco 11 · Adaptar código para automatizar tarefas

Automatizar tarefas repetitivas

Uma das realizações centrais da UC: adaptar código para automatizar tarefas que, sem código, seriam feitas à mão, devagar e com erros.

  • Scripts de tarefas: npm run build, npm run lint, npm run test encadeiam passos repetitivos num só comando.
  • Geração em lote: um script que lê uma lista de 50 exercícios de um .json e gera 50 páginas HTML automaticamente.
  • CI/CD: pipelines que correm testes e fazem deploy sozinhos a cada alteração de código.
  • Regra: automatiza o que se repete três ou mais vezes; automatizar algo único custa mais do que faz à mão.

Adaptar algoritmos a diferentes contextos

  • Um algoritmo genérico (ex.: ordenar uma lista) adapta-se ao contexto através de parâmetros (função de comparação, critério de ordenação).
  • Configuração por dados: em vez de mudar código, muda-se um ficheiro de configuração (.json, .env) para adaptar o comportamento.
  • Exemplo: o mesmo gerador de certificados adapta-se a cursos diferentes só ao mudar o template e os dados de entrada.
  • Esta flexibilidade é o que permite reutilizar o mesmo código generativo em vários projetos de conteúdos interativos.

Bloco 12 · Testar código em diferentes plataformas

Tipos de testes

  • Testes unitários: verificam uma função ou classe isolada (Jest, Vitest).
  • Testes de integração: verificam que várias peças funcionam juntas (ex.: gerador + template + ficheiro final).
  • Testes end-to-end (E2E): simulam o utilizador real no browser (Playwright, Cypress).
  • Testes de plataforma: correr o mesmo conteúdo interativo em browsers, sistemas operativos e tamanhos de ecrã diferentes.

Testar código gerado é ainda mais importante: o gerador pode ter um erro que se repete em todos os ficheiros que produz.

Testar em diferentes plataformas na prática

  • Matriz de testes: cruzar browsers (Chrome, Firefox, Safari) com dispositivos (desktop, tablet, telemóvel).
  • Ferramentas: DevTools em modo responsivo, emuladores, serviços como BrowserStack para testar em dispositivos reais remotos.
  • Acessibilidade entra aqui também: testar com teclado e leitor de ecrã, não só com rato.
  • Critério de desempenho da UC: garantir que a geração de código é escalável, incluindo escalar para plataformas diferentes sem reescrever tudo.

Bloco 13 · Segurança no código gerado

Vulnerabilidades comuns em código gerado

Código gerado automaticamente (por templates ou por IA) pode introduzir falhas se não for revisto.

  • Injeção: dados do utilizador inseridos diretamente numa query ou num template sem escapar, abre a porta a SQL injection e XSS.
  • Dependências desatualizadas: geradores que instalam pacotes antigos com vulnerabilidades conhecidas.
  • Segredos expostos: templates que copiam chaves de API ou palavras-passe de exemplo para o código real.
  • Aptidão da UC: evitar vulnerabilidades comuns; critério de desempenho: validar entradas e evitar práticas que originem falhas de segurança.

Boas práticas de segurança no código generativo

  • Escapar sempre dados que vêm do utilizador antes de os inserir em HTML, SQL ou comandos de sistema.
  • Validar o tipo e o formato de cada entrada, na fronteira do sistema, antes de gerar qualquer código a partir dela.
  • Rever o código gerado por IA ou por templates como se fosse escrito por outra pessoa, com o mesmo rigor.
  • Usar ferramentas de análise automática (linters, npm audit) para apanhar problemas antes de publicar.

Bloco 14 · Normas de segurança, saúde e ambiente

Segurança e saúde no trabalho

O trabalho de programação é sedentário e repetitivo: exige atenção à ergonomia e à saúde de quem o faz.

  • Postura: ecrã à altura dos olhos, antebraços apoiados, cadeira regulável.
  • Pausas regulares: a cada 50-60 minutos, para os olhos e para evitar lesões por esforço repetitivo (LER).
  • Iluminação e som: evitar reflexos no ecrã, ruído excessivo no espaço de trabalho.
  • Atitude avaliada na UC: responsabilidade pelas próprias ações, incluindo cuidar da própria saúde no posto de trabalho.

Normas de proteção ambiental

Programar tem impacto ambiental, mesmo sendo trabalho "digital".

  • Eficiência energética do código: código mais eficiente consome menos processamento e menos energia nos servidores.
  • Green coding: evitar processamento e armazenamento desnecessários (ex.: gerar só o que é preciso, não tudo "por garantia").
  • Equipamento: prolongar a vida útil de computadores, reciclar equipamento eletrónico corretamente.
  • Alojamento consciente: escolher serviços de hosting com práticas energéticas responsáveis, quando é possível decidir.

Bloco 15 · Fecho

Do princípio genérico ao código em produção

  • Programação genérica: escrever uma vez, reutilizar para muitos tipos.
  • Código generativo: templates, scaffolding e IA que escrevem código por nós, sempre revisto.
  • Design patterns: vocabulário e estrutura para problemas recorrentes.
  • Metaprogramação e tipagem dinâmica: código que se adapta e que examina outro código.
  • Frameworks flexíveis, testes em várias plataformas e segurança no código gerado fecham o ciclo até à produção.

Um técnico que domina código generativo entrega mais depressa, com menos erros repetidos e com o mesmo rigor de sempre.

Recapitulando

  • Programação genérica e tipagem dinâmica dão a base para código reutilizável em qualquer tipo de dados.
  • Código generativo: templates, scaffolding, frameworks e IA generativa aceleram a escrita de código repetitivo.
  • Design patterns (criação, estruturais, comportamentais) e metaprogramação dão estrutura e flexibilidade ao código.
  • Testar em diferentes plataformas e validar entradas garantem que o que se automatiza continua correto e seguro.
  • Normas de segurança, saúde e ambiente acompanham sempre o trabalho técnico.

Próximo: fichas e projeto, construir um gerador de componentes interativos de raiz.

NOTAS DO PROFESSOR - enfatizar: genérico significa "parametrizado por tipo", não "sem tipo". É o oposto de código solto/dinâmico sem controlo. - erro comum: confundir "genérico" com "qualquer coisa serve". Mostrar que os genéricos continuam a ser verificados pelo compilador. - analogia: uma forma de bolo (a lógica) que aceita recheios diferentes (os tipos), mas mantém sempre o mesmo processo.

NOTAS DO PROFESSOR - enfatizar: a escolha da linguagem muda ONDE o erro de tipo aparece, em compilação ou só em execução. Isso tem custo real em produção. - erro comum: achar que JavaScript "não tem" programação genérica. Tem, é só resolvida em execução (duck typing). - exemplo: mostrar a mesma função `primeiro(lista)` em JS (funciona com tudo, sem aviso) e em TS com `function primeiro<T>(lista: T[]): T` (com aviso se o tipo não bater certo).

NOTAS DO PROFESSOR - enfatizar: distinguir os três níveis (gerador de ficheiros, metaprogramação, IA) porque a UC pede os três. - erro comum: pensar que "código generativo" é só sinónimo de IA. É mais antigo e mais amplo que isso. - exemplo: um formulário de contacto com 12 campos repetidos é o caso de escola para gerar em vez de copiar e colar.

NOTAS DO PROFESSOR - enfatizar: uma meta linguagem tem sintaxe própria, mais simples que a linguagem final, precisamente para ser fácil de gerar ou de escrever à mão. - erro comum: confundir template de texto (substituição simples) com metaprogramação (código que manipula código em memória). São técnicas diferentes. - exemplo: mostrar um `.hbs` com `{{nome}}` a gerar um cartão de produto HTML para 50 produtos diferentes a partir de um só ficheiro de dados.

NOTAS DO PROFESSOR - enfatizar: scaffolding poupa tempo E garante consistência entre a equipa, ninguém inventa a sua própria estrutura de pastas. - erro comum: gerar o esqueleto e nunca mais o adaptar ao projeto real, deixando ficheiros de exemplo esquecidos. - exercício rápido: correr `npm create vite@latest` em conjunto e explorar a estrutura gerada.

NOTAS DO PROFESSOR - enfatizar: a IA generativa é uma técnica de código generativo entre outras, não é magia nem substitui o critério técnico. - erro comum: colar código gerado sem perceber o que faz. Perguntar sempre "consigo explicar esta linha à turma?" - analogia: é como um estagiário rápido mas sem experiência, produz muito depressa, mas precisa sempre de revisão de um sénior.

NOTAS DO PROFESSOR - enfatizar: um componente de framework é, na prática, um gerador de HTML parametrizado, a mesma ideia dos blocos anteriores. - erro comum: reinventar à mão o que o framework já resolve (ex.: atualizar manualmente o DOM em vez de deixar o framework fazê-lo). - exemplo: mostrar o mesmo cartão de produto como componente React com `props` versus copiado e colado 10 vezes em HTML estático.

NOTAS DO PROFESSOR - enfatizar: usar um template pronto não é "batota", é reutilização profissional, desde que se perceba o que ele faz. - erro comum: escolher um framework só porque é o mais falado, sem avaliar se serve o projeto concreto. - exercício rápido: comparar em conjunto dois starters de projeto (ex.: Vite + React vs Next.js) e listar diferenças.

NOTAS DO PROFESSOR - enfatizar: um pattern é uma IDEIA, não uma biblioteca. Pode implementar-se de formas ligeiramente diferentes consoante a linguagem. - erro comum: usar patterns "porque sim", complicando código simples. Um pattern só vale a pena quando resolve um problema real. - analogia: os patterns são como técnicas de culinária (saltear, gratinar), receitas gerais que se aplicam a pratos diferentes.

NOTAS DO PROFESSOR - enfatizar: os princípios vêm primeiro, os patterns são consequência. Não é preciso decorar 23 patterns, é preciso perceber os princípios. - erro comum: aplicar SOLID ao pé da letra em projetos pequenos, criando complexidade desnecessária. - pergunta à turma: dão um exemplo de código duplicado que já viram (ou escreveram) e que violava o DRY?

NOTAS DO PROFESSOR - enfatizar: o objetivo comum é esconder o "novo" (new/construtor) atrás de uma interface mais simples e flexível. - erro comum: abusar do Singleton para tudo, criando estado global escondido, difícil de testar. - exemplo: mostrar a Factory de componentes interativos no quadro, com um `switch` sobre o tipo.

NOTAS DO PROFESSOR - enfatizar: Observer é o pattern por trás de quase todos os eventos de UI (`addEventListener`) e do estado reativo em React/Vue. - erro comum: confundir Adapter (compatibilidade) com Decorator (extensão de comportamento). Pedir à turma a diferença por palavras próprias. - exercício rápido: identificar o Strategy num sistema de pontuação de quiz com "modo fácil" e "modo difícil".

NOTAS DO PROFESSOR - enfatizar: herança é "é um" (Quiz É um ComponenteInterativo). Confirmar sempre esta relação antes de usar `extends`. - erro comum: herdar só para reutilizar código sem existir uma relação lógica real. Nesse caso, composição é melhor. - exemplo: mostrar uma segunda subclasse, `Galeria extends ComponenteInterativo`, para reforçar o padrão.

NOTAS DO PROFESSOR - enfatizar: polimorfismo é o que torna a Factory do bloco anterior útil, cria objetos diferentes que se usam da mesma forma depois. - erro comum: fazer `if (item instanceof Quiz) ... else if (item instanceof Galeria) ...` em vez de deixar o polimorfismo tratar disso. - pergunta à turma: porque é que isto facilita "adaptar código para automatizar tarefas" (um dos objetivos da UC)?

NOTAS DO PROFESSOR - enfatizar: metaprogramação é "um nível acima" da programação normal, código sobre código. É poderosa e também mais difícil de depurar. - erro comum: abusar de metaprogramação em código simples, tornando-o "mágico" e difícil de seguir por outra pessoa. - analogia: é como um livro de instruções que sabe reescrever-se a si próprio consoante quem o lê.

NOTAS DO PROFESSOR - enfatizar: decorators são metaprogramação aplicada, "código que envolve código". Ligar ao Decorator pattern do bloco 6. - erro comum: pensar que decorators são exclusivos do TypeScript/Angular. A ideia existe em várias linguagens (Python `@`, Java anotações). - exemplo: mostrar rapidamente um `Proxy` simples em consola a intercetar uma leitura de propriedade.

NOTAS DO PROFESSOR - enfatizar: duck typing é genericidade sem sintaxe de genéricos, o preço é perder a verificação em compilação. - erro comum: assumir que um objeto tem um método sem verificar, gerando "TypeError: X is not a function" em produção. - pergunta à turma: porque é que TypeScript existe se JavaScript já é flexível? (segurança e deteção precoce de erros).

NOTAS DO PROFESSOR - enfatizar: tipagem dinâmica não dispensa validação, só a move para tempo de execução. Alguém tem de a fazer. - erro comum: confiar cegamente nos dados que chegam de um formulário ou API externa sem validar o tipo. - exercício rápido: escrever uma função `validarIdade(valor)` que confirma se é número antes de o usar.

NOTAS DO PROFESSOR - enfatizar: "flexível" não significa "sem opinião nenhuma". Bons frameworks têm convenções fortes E pontos de extensão claros. - erro comum: lutar contra as convenções do framework em vez de as aprender, reinventando funcionalidades que já existem. - exemplo: mostrar um hook personalizado simples em React (`useContador`) que reutiliza lógica entre componentes.

NOTAS DO PROFESSOR - enfatizar: escolher biblioteca é uma decisão de equipa e de longo prazo, não só "o que resolve o problema hoje". - erro comum: instalar dezenas de dependências pequenas para tarefas triviais, aumentando o risco de segurança e o peso do projeto. - pergunta à turma: como verificam se uma biblioteca no npm ainda é mantida? (data do último update, issues abertas, downloads).

NOTAS DO PROFESSOR - enfatizar: automatizar não é só "programar mais", é reconhecer padrões repetitivos e valer a pena investir tempo a resolvê-los uma vez. - erro comum: passar horas a automatizar uma tarefa que só se faz uma vez. Avaliar sempre o retorno do investimento. - exemplo: mostrar um script simples que renomeia 20 ficheiros de imagem seguindo uma convenção, em vez de o fazer um a um.

NOTAS DO PROFESSOR - enfatizar: adaptar um algoritmo a um novo contexto não devia exigir reescrever a lógica, só mudar parâmetros ou dados. - erro comum: copiar e colar um script inteiro só para mudar um valor, em vez de o parametrizar. - exercício rápido: pedir à turma para identificar o que mudaria e o que ficaria igual num gerador de certificados para outro curso.

NOTAS DO PROFESSOR - enfatizar: um erro num gerador propaga-se a tudo o que ele gera, testar o gerador vale mais do que testar um resultado isolado. - erro comum: testar só no browser do desenvolvedor e assumir que funciona em todo o lado. - exemplo: mostrar o mesmo componente interativo a falhar em Safari por usar uma função que só existe no Chrome.

NOTAS DO PROFESSOR - enfatizar: testar em plataformas diferentes não é opcional em conteúdos interativos, o público final usa dispositivos muito variados. - erro comum: deixar os testes de plataforma para o fim do projeto, quando corrigir já é caro. - exercício rápido: testar um componente feito na aula em três larguras de ecrã diferentes no DevTools.

NOTAS DO PROFESSOR - enfatizar: quanto mais automático é o processo, mais depressa um erro de segurança se multiplica por todos os ficheiros gerados. - erro comum: confiar que "o gerador sabe o que faz" e saltar a revisão de segurança do código produzido. - exemplo: mostrar um template que insere `{{comentario}}` diretamente em HTML sem escapar, e o que acontece com `<script>alert(1)</script>`.

NOTAS DO PROFESSOR - enfatizar: segurança no código generativo é responsabilidade de quem integra, não do gerador ou da IA. - erro comum: assumir que porque o código "corre sem erros" está seguro. Correr sem erro não é o mesmo que ser seguro. - pergunta à turma: que dados de um formulário de conteúdo interativo (nome, comentário) precisam de ser escapados antes de mostrar no ecrã?

NOTAS DO PROFESSOR - enfatizar: estas normas não são "extra", fazem parte do referencial oficial da UC e devem ser tratadas com o mesmo rigor técnico. - erro comum: passar horas seguidas sem pausas "porque o código está quase pronto". Reforçar que a pausa poupa erros e saúde. - exercício rápido: cada aluno ajusta a sua própria postura e altura de ecrã na sala, com a orientação do professor.

NOTAS DO PROFESSOR - enfatizar: a ligação entre código eficiente e ambiente é real, um gerador que produz ficheiros desnecessários também gasta energia a mais. - erro comum: achar que o impacto ambiental do software é irrelevante por não ser "físico". É físico, está nos data centers. - pergunta à turma: que prática das aulas anteriores (ex.: tree-shaking, gerar só o necessário) também ajuda o ambiente?

NOTAS DO PROFESSOR - enfatizar: recapitular a cadeia completa, do princípio abstrato (genérico) até à prática concreta (testar, segurança, ambiente). - erro comum: ver os blocos como assuntos separados. Reforçar que todos se apoiam no mesmo objetivo: escrever menos código repetido, com mais confiança. - anunciar: as fichas treinam patterns, metaprogramação e geração de código; o projeto constrói um gerador de componentes interativos de raiz.