Padrão Factory
Parte da seção Programação Orientada a Objetos do Journey de C# da Coddy. Lição 53 de 70.
O padrão Factory é um padrão de criação que delega a criação de objetos a um método ou classe separado. Em vez de usar new diretamente no seu código, você solicita a uma fábrica que crie objetos para você. Isso centraliza a lógica de criação e torna seu código mais flexível.
Considere um cenário em que você precisa criar diferentes tipos de documentos. Sem uma fábrica, seu código fica fortemente acoplado a classes específicas:
// Sem Factory - lógica de criação espalhada
IDocument doc;
if (type == "pdf")
doc = new PdfDocument();
else if (type == "word")
doc = new WordDocument();Uma fábrica encapsula essa tomada de decisão em um só lugar:
public interface IDocument
{
void Open();
}
public class PdfDocument : IDocument
{
public void Open() => Console.WriteLine("Opening PDF");
}
public class WordDocument : IDocument
{
public void Open() => Console.WriteLine("Opening Word");
}
public class DocumentFactory
{
public IDocument Create(string type)
{
return type switch
{
"pdf" => new PdfDocument(),
"word" => new WordDocument(),
_ => throw new ArgumentException("Unknown type")
};
}
}Agora, o código do cliente simplesmente solicita o que precisa sem conhecer as classes concretas:
var factory = new DocumentFactory();
IDocument doc = factory.Create("pdf");
doc.Open(); // Abrindo PDFO padrão Factory se destaca quando você precisa adicionar novos tipos posteriormente. Adicionar um SpreadsheetDocument exige alterações apenas na factory, e não em todos os lugares onde os documentos são criados. Essa separação torna sua base de código mais fácil de manter e testar.
Desafio
FácilVamos criar um sistema de notificações usando o padrão Factory. Em vez de criar diretamente diferentes tipos de notificações em todo o seu código, você centralizará a lógica de criação em uma classe factory que decide qual notificação criar com base em um identificador de string simples.
Você organizará seu código em três arquivos:
Notification.cs: Defina uma interfaceINotificationno namespaceNotificationscom um único métodoSend(string message)que retorna uma string. Em seguida, crie três classes que implementam essa interface:EmailNotification- retorna"Email: {message}"SmsNotification- retorna"SMS: {message}"PushNotification- retorna"Push: {message}"
NotificationFactory.cs: Crie uma classeNotificationFactoryno mesmo namespace com um métodoCreate(string type)que retorna oINotificationapropriado com base na string de tipo:"email"retorna umEmailNotification"sms"retorna umSmsNotification"push"retorna umPushNotification
EmailNotificationcomo padrão.Program.cs: Reúna tudo criando uma instância da factory e usando-a para criar notificações com base na entrada. A factory cuida de toda a decisão sobre qual classe concreta instanciar.
Você receberá duas entradas:
- O tipo de notificação (por exemplo,
sms) - A mensagem a ser enviada (por exemplo,
Your order has shipped)
Use sua factory para criar o tipo de notificação apropriado, depois chame seu método Send com a mensagem e imprima o resultado.
Por exemplo, se as entradas forem push e Meeting in 5 minutes, a saída deverá ser:
Push: Meeting in 5 minutesObserve como seu código principal nunca usa new EmailNotification() ou algo semelhante — ele simplesmente pede à factory o que precisa. Se posteriormente você adicionar uma SlackNotification, precisará atualizar apenas a factory, e não todos os lugares que criam notificações!
Experimente você mesmo
using System;
using Notifications;
class Program
{
public static void Main(string[] args)
{
// Ler entrada
string type = Console.ReadLine();
string message = Console.ReadLine();
// TODO: Crie uma instância de NotificationFactory
// TODO: Use a factory para criar a notificação apropriada
// TODO: Chame o método Send e imprima o resultado
}
}
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Programação Orientada a Objetos
1Fundamentos de POO
Arquivos ExternosNamespaces e DiretivasIntrodução a Classes e ObjetosA Palavra-chave 'this'Métodos e ParâmetrosCampos vs PropriedadesConstrutoresInicializadores de ObjetosRecapitulação - Calculadora Simples4Herança
Sintaxe Básica de Herança (:)A Palavra-chave 'base'Palavras-chave Virtual e OverrideClasses SeladasA Classe Base 'object'Recapitulação - Hierarquia de Funcionários7Recursos Avançados
Sobrecarga de OperadoresIndexadores (this[])Sobrescrita de ToString()Métodos de ExtensãoRecapitulação - Lista Personalizada10Padrões de Projeto Parte 1
Introdução aos Padrões de ProjetoSingleton Thread-SafePadrão FactoryPadrão Observer (Eventos)Padrão Strategy2Propriedades e Membros Estáticos
Propriedades AutoimplementadasPropriedades de Apenas Leitura/EscritaCampos e Métodos EstáticosClasses EstáticasMembros com Corpo de Expressão5Polimorfismo e Interfaces
Polimorfismo: Compilação vs ExecuçãoInterface vs Classe AbstrataMúltiplas InterfacesInterfaces ExplícitasUpcasting e DowncastingRecapitulação - Calculadora de Formas8Conceitos Avançados de POO
Composição sobre HerançaGenerics (Classes e Métodos)Delegates e EventosAtributos e ReflectionIDisposable e a Instrução usingFundamentos de Injeção de Dependência11Padrões de Projeto Parte 2
Padrão CommandPadrão AdapterPadrão DecoratorPadrão Template MethodPadrão StatePadrão Composite3Arquitetura de Classes
Dados de Instância vs EstáticosPalavras-chave 'readonly' e 'const'Campos de SuporteRecapitulação - Gerenciador de Conta Bancária6Encapsulamento
Modificadores de AcessoPropriedades para EncapsulamentoImplementação de Ocultação de DadosPadrões de ImutabilidadeRecapitulação - Registros de Estudantes9Argumentos Variáveis
A Palavra-chave 'params'Parâmetros OpcionaisArgumentos NomeadosSobrecarga de MétodosPratique por conta própria: Compilador de C# online