Este curso pode ser ministrado em exclusivo para a sua organização, nas suas instalações, nas nossas ou online, com o programa ajustado aos objetivos da equipa.
Solicitar proposta(não existem exames)
Melhorar o desenho orientado a objetos com os princípios S.O.L.I.D.
S — responsabilidade única
O — aberto/fechado
L — substituição de Liskov
I — segregação de interfaces
D — inversão de dependências
Introdução aos patterns
O que é um pattern?
O Gang of Four: Erich Gamma, Ralph Johnson, Richard Helm e John Vlissides.
Diferentes tipos de design pattern: creational, structural e behavioral.
Patterns por todo o lado: a diferença entre patterns de implementação, de desenho e de arquitetura.
Quando aplicar patterns — e quando não os aplicar
Alguns anti-patterns, como o Loosey-Goosey
Singleton pattern
O que é um Singleton?
Opções de implementação do Singleton em .NET
Utilizar dependency injection
Por que selar classes é boa ideia
LAB: construir um Singleton em .NET
Reutilização de código com Template Method
Template Method — adiar partes exatas de um algoritmo para classes derivadas, delegates e outros
LAB: construir um Template Method para um jogo de tabuleiro
Criação abstrata de objetos com factories
Factory Method — delegar e esconder numa factory a criação de objetos
Abstract Factory — abstrair numa factory a criação de famílias de objetos
LAB: implementar uma Abstract Factory
Os patterns Strategy e Chain-of-Responsibility
Strategy — o Template Method sem a herança incómoda
LAB: ordenar objetos com strategies
Chain of Responsibility — a strategy que percorre uma cadeia de strategies
LAB: usar uma Chain of Responsibility para implementar um Builder
Collection patterns
Iterator — uma forma genérica de percorrer coleções; o yield é seu amigo; iterar uma coleção de forma assíncrona
Considerações de desempenho na implementação de IEnumerable
Utilizar frozen collections
Behavioral pattern: State e máquinas de estados
Reconhecer o problema: lógica condicional espalhada por uma classe
State — encapsular comportamento em objetos de estado e tornar as transições explícitas
Modelar fluxos de trabalho como máquinas de estados finitos
Usar a biblioteca Stateless: definir estados, triggers e guards em .NET
Visualizar máquinas de estados para documentação e depuração
LAB: implementar um leitor multimédia (reproduzir/pausa/parar) com o State pattern e a biblioteca Stateless
Structural pattern: Flyweight
Reconhecer o problema: milhares de objetos quase idênticos a consumir memória em excesso
Flyweight — separar o estado intrínseco (partilhado) do estado extrínseco (contextual)
Implementar uma factory de Flyweight com cache em .NET
Como o .NET já aplica o Flyweight: string interning e cache de inteiros pequenos
Compromissos: quando o Flyweight ajuda — e quando acrescenta complexidade desnecessária
Structural pattern: Composite
Composite — construir hierarquias parte-todo com uma interface uniforme
Nós folha vs. nós compostos: quando acrescentar a gestão de filhos à interface do componente
Composite em .NET: expression trees e árvores de controlos de interface
Behavioral pattern: Interpreter
Interpreter — representar as regras de uma gramática como hierarquia de classes
Construir e avaliar uma árvore de sintaxe abstrata (AST)
Como as expression trees do LINQ usam o Interpreter — e como construir a sua
LAB: construir um avaliador simples de expressões aritméticas com o Interpreter
Creational pattern: Builder
Builder — construção passo a passo de objetos complexos
APIs de builder fluentes: encadear métodos para uma construção legível e explícita na intenção
Builder em .NET: WebApplicationBuilder, IHostBuilder e builders de dados de teste
Classes director: encapsular sequências de construção comuns
LAB: analisar expressões com o Builder pattern
Behavioral pattern: Visitor
Visitor — separar os algoritmos da estrutura de objetos sobre a qual atuam
Double dispatch: como o Accept e o Visit funcionam em conjunto
Construir um pretty-printer com o Visitor clássico
Alternativa moderna: pattern matching em C# com switch expressions
Usar dynamic dispatch para evitar o código repetitivo do Accept
Compromissos: Visitor clássico vs. pattern matching — quando escolher cada um
LAB: implementar um Visitor que gera vários formatos de saída a partir da mesma hierarquia de objetos
Behavioral pattern: Observer
Observer — desacoplar quem publica de quem subscreve
Eventos e delegates em .NET: a implementação do Observer que vem de origem
As interfaces IObservable<T> e IObserver<T> como alternativa assente em push
LAB: construir um teletipo de cotações com o Observer
Behavioral pattern: Mediator
Mediator — um centro único que substitui as referências diretas entre objetos
Observer vs. Mediator: quando usar cada um
Implementar corretamente o INotifyPropertyChanged — e evitar o anti-padrão das strings soltas
Usar nameof() e source generators para tornar as notificações de propriedade seguras à refatoração
A biblioteca MediatR: aplicar o Mediator numa arquitetura de serviços e handlers
LAB: refatorar um formulário fortemente acoplado para um desenho assente no Mediator
Structural pattern: Adapter
Adapter — ligar interfaces incompatíveis sem tocar em nenhuma das classes
Object adapter vs. class adapter: composição vs. herança
Adaptar bibliotecas de terceiros às interfaces do seu domínio
Adapters bidirecionais: envolver os dois sentidos
LAB: construir um adapter com expressions e o DLR
Structural pattern: Decorator
Decorator — acrescentar comportamento de forma transparente, sem alterar quem chama
Empilhar decorators: compor preocupações transversais (logging, caching, validação)
Decorator em .NET: Stream, middleware do ASP.NET Core e decoração via DI
Registar decorators num contentor de DI
LAB: acrescentar operações de ordenação com decorators
Structural pattern: Proxy
Proxy — controlar o acesso ao objeto real
Virtual proxy: adiar a criação dispendiosa de um objeto até ser necessária
Protection proxy: impor autorização antes de delegar as chamadas
Remote proxy: fazer com que uma chamada de rede pareça uma chamada local
Proxy vs. Decorator: a mesma estrutura, intenções diferentes
Esconder detalhes de implementação com Facade
Facade — esconder de quem chama a complexidade dos subsistemas
Utilização de value objects
Evitar o anti-padrão da obsessão por primitivos
Boas práticas na construção de value objects
LAB: construir um value object de endereço de correio
Acesso a dados com os patterns Specification e Repository
Repository — abstrair o acesso a dados
LAB: implementar um Repository com Entity Framework Core
Specification — encapsular queries complexas
Usar o Specification pattern com Entity Framework Core
LAB: implementar uma Specification para um Repository
Utilização do Result pattern
As exceções são dispendiosas
Utilizar o Result pattern
Melhorar o Result pattern com sintaxe LINQ
LAB: usar o Result pattern numa aplicação MVC
Construir interfaces flexíveis com Model-View-Whatever
Model-View-Controller: um padrão antigo de volta à moda
O padrão MVC do ASP.NET
MVVM em Blazor — o MVW a tirar partido de capacidades poderosas de data binding
Command: encapsular comportamento em objetos
Implementar commands com closures
Design patterns aplicados: desenvolver a sua própria biblioteca reutilizável
Acrescentar o Command pattern do GoF ao MVVM
Usar interfaces para ganhar flexibilidade
Construir objetos de comando — estender a interface ICommand
Acrescentar funcionalidade de anular e refazer ao Command pattern
Usar uma classe CommandManager
Desafio: encaixar os nossos commands no MVVM sem grandes alterações
Implementar anular/refazer com o Memento pattern
Decidir se vale a pena acrescentar o Prototype pattern
Ideias para prosseguir com o Command pattern
LAB: implementar a lógica de anular/refazer como biblioteca reutilizável
Este curso pode ser ministrado em exclusivo para a sua organização, nas suas instalações, nas nossas ou online, com o programa ajustado aos objetivos da equipa.
Solicitar propostaPresencial26/10/2026 14:00–17:00
Online02/12/2026 09:30–12:30
Presencial09/11/2026 14:00–17:00
Online21/12/2026 09:30–12:30
Online01/03/2027 14:00–17:30
Assistente Actual Training IA
Respostas automáticas sobre cursos e datas
Assistente com IA — pode conter imprecisões; confirme connosco o que for decisivo. As conversas são registadas para melhorar o serviço; não escreva dados pessoais — para isso use o formulário de contacto. Saiba mais na política de privacidade.