Introdução
No mundo do desenvolvimento de software, frequentemente nos deparamos com problemas recorrentes. É aí que entram os Design Patterns (Padrões de Projeto): soluções comprovadas para resolver esses problemas de maneira eficiente e elegante. Esses padrões ajudam a melhorar a manutenção, escalabilidade e legibilidade do código.
No C#, os Design Patterns são amplamente utilizados para estruturar aplicações de maneira robusta, independentemente do tamanho ou complexidade do projeto. Neste artigo, exploraremos os padrões mais usados, como Singleton, Factory, Observer e Repository, com exemplos práticos de aplicação.
O Que São Design Patterns?
Design Patterns são soluções reutilizáveis para problemas comuns de design de software. Eles não são pedaços de código prontos, mas sim modelos ou guias que podem ser adaptados ao seu contexto.
No C#, os padrões são amplamente suportados graças à flexibilidade da linguagem e aos recursos avançados, como interfaces, classes abstratas e delegados.
Principais Categorias de Design Patterns
Os padrões são geralmente classificados em três categorias:
-
Padrões Criacionais
- Tratam da criação de objetos, promovendo maior flexibilidade e reutilização.
- Exemplos: Singleton, Factory Method, Abstract Factory.
-
Padrões Estruturais
- Ajudam a compor objetos para formar estruturas maiores.
- Exemplos: Adapter, Decorator, Composite.
-
Padrões Comportamentais
- Focam na comunicação entre objetos.
- Exemplos: Observer, Strategy, Command.
Padrão Singleton
O Singleton garante que uma classe tenha apenas uma única instância durante toda a execução do programa. É muito usado para gerenciar conexões de banco de dados, logging ou configurações globais.
Exemplo no C#:
public sealed class Singleton
{
private static Singleton _instancia;
private static readonly object _lock = new object();
private Singleton() { }
public static Singleton Instancia
{
get
{
lock (_lock)
{
if (_instancia == null)
{
_instancia = new Singleton();
}
return _instancia;
}
}
}
public void ExibirMensagem()
{
Console.WriteLine("Exemplo de Singleton!");
}
}
// Uso
class Program
{
static void Main(string[] args)
{
Singleton instancia = Singleton.Instancia;
instancia.ExibirMensagem();
}
}
Padrão Factory Method
O Factory Method permite criar objetos sem especificar a classe exata que será instanciada. Ele delega a responsabilidade de criação para subclasses, tornando o código mais flexível.
Exemplo no C#:
public abstract class Criador
{
public abstract IProduto CriarProduto();
}
public class CriadorConcreto : Criador
{
public override IProduto CriarProduto()
{
return new ProdutoConcreto();
}
}
public interface IProduto
{
void Operar();
}
public class ProdutoConcreto : IProduto
{
public void Operar()
{
Console.WriteLine("Produto criado!");
}
}
// Uso
class Program
{
static void Main(string[] args)
{
Criador criador = new CriadorConcreto();
IProduto produto = criador.CriarProduto();
produto.Operar();
}
}
Padrão Observer
O Observer permite que um objeto (o "observado") notifique automaticamente outros objetos (os "observadores") quando houver mudanças no seu estado. É ideal para sistemas de eventos ou notificações.
Exemplo no C#:
using System;
using System.Collections.Generic;
public interface IObservador
{
void Atualizar(string mensagem);
}
public class ObservadorConcreto : IObservador
{
private string _nome;
public ObservadorConcreto(string nome)
{
_nome = nome;
}
public void Atualizar(string mensagem)
{
Console.WriteLine($"{_nome} recebeu: {mensagem}");
}
}
public class Observado
{
private List<IObservador> _observadores = new List<IObservador>();
public void AdicionarObservador(IObservador observador)
{
_observadores.Add(observador);
}
public void RemoverObservador(IObservador observador)
{
_observadores.Remove(observador);
}
public void Notificar(string mensagem)
{
foreach (var observador in _observadores)
{
observador.Atualizar(mensagem);
}
}
}
// Uso
class Program
{
static void Main(string[] args)
{
Observado observado = new Observado();
IObservador obs1 = new ObservadorConcreto("Observador 1");
IObservador obs2 = new ObservadorConcreto("Observador 2");
observado.AdicionarObservador(obs1);
observado.AdicionarObservador(obs2);
observado.Notificar("Evento ocorreu!");
}
}
Padrão Repository
O Repository é usado para encapsular a lógica de acesso a dados, permitindo que a camada de negócios se comunique com os dados de forma desacoplada.
Exemplo no C#:
using System;
using System.Collections.Generic;
public interface IRepository<T>
{
void Adicionar(T item);
IEnumerable<T> ObterTodos();
}
public class Repository<T> : IRepository<T>
{
private List<T> _itens = new List<T>();
public void Adicionar(T item)
{
_itens.Add(item);
}
public IEnumerable<T> ObterTodos()
{
return _itens;
}
}
// Uso
class Program
{
static void Main(string[] args)
{
IRepository<string> repository = new Repository<string>();
repository.Adicionar("Item 1");
repository.Adicionar("Item 2");
foreach (var item in repository.ObterTodos())
{
Console.WriteLine(item);
}
}
}
Conclusão
Os Design Patterns são ferramentas indispensáveis para qualquer desenvolvedor que busca escrever código limpo, eficiente e escalável. Cada padrão resolve um tipo específico de problema, e sua aplicação depende do contexto do projeto. Comece experimentando padrões como Singleton, Factory, Observer e Repository e observe como eles podem transformar a arquitetura do seu código.
Qual desses padrões você já utiliza? Se você tem dúvidas ou quer explorar mais sobre um deles, deixe um comentário!
Nenhum comentário:
Postar um comentário