Factory Method
O Factory Method é um padrão criacional utilizado quando queremos criar objetos sem deixar que o código cliente precise conhecer diretamente a classe concreta que será instanciada.
Em vez de fazer:
const notification = new EmailNotification();
podemos delegar a criação para um método especializado:
const notification = creator.createNotification();
A principal ideia é:
Deixar que subclasses ou implementações específicas decidam qual objeto concreto será criado.
O problema
Imagine um sistema que envia notificações.
Inicialmente temos:
class EmailNotification {
send(message: string) {
console.log(`Email: ${message}`);
}
}
O código poderia fazer:
const notification =
new EmailNotification();
notification.send("Olá!");
Porém, se quisermos adicionar SMS:
class SmsNotification {
send(message: string) {
console.log(`SMS: ${message}`);
}
}
Agora o código cliente precisa saber qual classe deve instanciar.
Isso pode gerar muito código condicional:
if (type === "email") {
return new EmailNotification();
}
if (type === "sms") {
return new SmsNotification();
}
O Factory Method ajuda a separar essa responsabilidade.
Implementação
Primeiro criamos uma interface:
interface Notification {
send(message: string): void;
}
Agora criamos as implementações:
class EmailNotification
implements Notification {
send(message: string) {
console.log(
`Enviando email: ${message}`
);
}
}
class SmsNotification
implements Notification {
send(message: string) {
console.log(
`Enviando SMS: ${message}`
);
}
}
Criamos então o Creator:
abstract class NotificationCreator {
abstract createNotification():
Notification;
send(message: string) {
const notification =
this.createNotification();
notification.send(message);
}
}
Agora temos os creators concretos:
class EmailNotificationCreator
extends NotificationCreator {
createNotification(): Notification {
return new EmailNotification();
}
}
class SmsNotificationCreator
extends NotificationCreator {
createNotification(): Notification {
return new SmsNotification();
}
}
Podemos utilizar:
const creator =
new EmailNotificationCreator();
creator.send("Olá!");
Ou:
const creator =
new SmsNotificationCreator();
creator.send("Olá!");
O código cliente não precisa conhecer diretamente:
new EmailNotification()
ou:
new SmsNotification()
Quando usar?
O Factory Method é útil quando:
- A criação de objetos pode variar.
- Você possui diferentes implementações de uma mesma interface.
- Quer evitar
newespalhado pelo código. - A classe base possui um fluxo comum, mas subclasses definem qual objeto utilizar.
Resumo
Código cliente
↓
Creator
↓
Factory Method
↓
Produto concreto
A ideia principal é:
Delegar a criação de um objeto para uma implementação especializada.
É especialmente útil quando queremos criar diferentes tipos de objetos mantendo o código cliente desacoplado das classes concretas.