Паттерн «Фабричный метод» (Factory Method)
Описание
Паттерн «Фабричный метод» (Factory Method) — это порождающий паттерн проектирования. Он помогает нам создавать объекты разного типа, не зная заранее, какого именно типа объект будет создан. Вместо этого мы создаём объект через специальный метод — «фабричный метод». Этот метод определён в базовом классе, а в классах-наследниках он реализуется так, чтобы возвращать нужный тип объекта. Т.е. паттерн создаёт объекты через специальный метод, а не через прямой вызов оператора new.
Все фабричные паттерны инкапсулируют операции создания объектов. Паттерн «Фабричный метод» позволяет подклассам решить, какой объект следует создать.
Пример: Кредитные карты
Можно открыть разные типы кредитных карт: Visa, MasterCard и UnionPay. Каждая из этих карт имеет свои лимиты по кредиту и годовую комиссию. Нам нужно создать каждую из этих карт в зависимости от того, что выберет клиент, и ввести для них общие методы (например, узнать тип карты, лимит и годовую комиссию)
Интерфейс Card
Интерфейс определяет базовые методы для всех типов карт.
interface Card {
getCardType(): string;
getCreditLimit(): number;
getAnnualCharge(): number;
}Конкретные карты
Каждый тип карты реализует интерфейс Card и предоставляет собственные лимиты и условия.
class VisaCard implements Card {
public getCardType(): string {
return 'Visa';
}
public getCreditLimit(): number {
return 50000;
}
public getAnnualCharge(): number {
return 1000;
}
}
class MasterCard implements Card {
public getCardType(): string {
return 'MasterCard';
}
public getCreditLimit(): number {
return 75000;
}
public getAnnualCharge(): number {
return 1500;
}
}
class UnionPayCard implements Card {
public getCardType(): string {
return 'UnionPay';
}
public getCreditLimit(): number {
return 60000;
}
public getAnnualCharge(): number {
return 1200;
}
}Фабричный метод CardFactory
Создадим абстрактный класс CardFactory, который будет определять фабричный метод createCard. Конкретные классы будут наследовать CardFactory и реализовывать создание определённого типа карты.
abstract class CardFactory {
public abstract createCard(): Card;
}Конкретные фабрики
Каждая фабрика будет создавать свой конкретный тип карты.
class VisaCardFactory extends CardFactory {
public createCard(): Card {
return new VisaCard();
}
}
class MasterCardFactory extends CardFactory {
public createCard(): Card {
return new MasterCard();
}
}
class UnionPayCardFactory extends CardFactory {
public createCard(): Card {
return new UnionPayCard();
}
}Пример использования фабрик
function getCardDetails(factory: CardFactory): void {
const card = factory.createCard();
console.log(`Тип карты: ${card.getCardType()}`);
console.log(`Лимит по карте: ${card.getCreditLimit()}`);
console.log(`Годовая комиссия: ${card.getAnnualCharge()}`);
}
// Создаём карту Visa
const visaFactory = new VisaCardFactory();
getCardDetails(visaFactory);
// Создаём карту MasterCard
const masterCardFactory = new MasterCardFactory();
getCardDetails(masterCardFactory);
// Создаём карту UnionPay
const unionPayFactory = new UnionPayCardFactory();
getCardDetails(unionPayFactory);Преимущества
- Изоляция логики создания объектов: клиенты не знают, какой тип объекта будет создан, и работают с ним через общий интерфейс.
- Расширяемость: легко добавить новый тип карты (например, MIR) — просто добавив новый класс и фабрику для него, не затрагивая существующий код.
Заключение
Паттерн «Фабричный метод» позволяет отделить логику создания объектов от их использования, что делает код гибким и модульным. В данном примере для создания различных типов карт используется соответствующая фабрика, которая скрывает логику создания и настройки карты от основного кода.