Какие паттерны проектирования вы использовали на практике?
Sobes Copilot
Получайте ответы в реальном времени
Ответ от нейросети
sobes.tech AI
На практике я применял следующие паттерны проектирования:
-
Фабричный метод (Factory Method): Для создания объектов разных типов без указания конкретного класса создания. Удобно при работе с различными источниками данных или конфигурациями.
// Пример использования фабричного метода class DataReader { read() { throw new Error("Method not implemented"); } } class FileReader extends DataReader { read() { console.log("Reading data from file..."); } } class NetworkReader extends DataReader { read() { console.log("Reading data from network..."); } } class DataReaderFactory { createReader(type) { switch (type) { case "file": return new FileReader(); case "network": return new NetworkReader(); default: throw new Error("Unknown reader type"); } } } const factory = new DataReaderFactory(); const fileReader = factory.createReader("file"); fileReader.read(); -
Одиночка (Singleton): Для гарантии существования только одного экземпляра класса и предоставления глобальной точки доступа к нему. Часто используется для менеджеров конфигурации или подключений к базам данных.
// Пример использования одиночки class ConfigManager { constructor() { if (ConfigManager.instance) { return ConfigManager.instance; } this.config = {}; ConfigManager.instance = this; } setConfig(key, value) { this.config[key] = value; } getConfig(key) { return this.config[key]; } } const instance1 = new ConfigManager(); const instance2 = new ConfigManager(); console.log(instance1 === instance2); // true -
Наблюдатель (Observer): Для реализации связи "один-ко-многим", где при изменении состояния одного объекта (издателя) автоматически оповещаются все зависимые объекты (подписчики). Используется в системах уведомлений, реактивных интерфейсах.
// Пример использования наблюдателя class Observable { constructor() { this.observers = []; } subscribe(observer) { this.observers.push(observer); } unsubscribe(observer) { this.observers = this.observers.filter(obs => obs !== observer); } notify(data) { this.observers.forEach(observer => observer.update(data)); } } class Observer { update(data) { console.log("Received update:", data); } } const observable = new Observable(); const observer1 = new Observer(); const observer2 = new Observer(); observable.subscribe(observer1); observable.subscribe(observer2); observable.notify("New data available!"); -
Стратегия (Strategy): Для определения семейства алгоритмов, инкапсуляции каждого из них и обеспечения их взаимозаменяемости. Позволяет алгоритму меняться независимо от клиентов, его использующих. Применяется для различных вариантов обработки данных или выполнения операций.
// Пример использования стратегии class PaymentStrategy { pay(amount) { throw new Error("Method not implemented"); } } class CreditCardPayment extends PaymentStrategy { pay(amount) { console.log(`Paying ${amount} using Credit Card`); } } class PayPalPayment extends PaymentStrategy { pay(amount) { console.log(`Paying ${amount} using PayPal`); } } class PaymentContext { setStrategy(strategy) { this.strategy = strategy; } executePayment(amount) { this.strategy.pay(amount); } } const context = new PaymentContext(); context.setStrategy(new CreditCardPayment()); context.executePayment(100); context.setStrategy(new PayPalPayment()); context.executePayment(50); -
Декоратор (Decorator): Для динамического добавления новой функциональности объекту без изменения его структуры. Обертывает существующий объект, предоставляя тот же интерфейс, что и обернутый объект, но с добавленной функциональностью. Удобно для логгирования, валидации, кеширования.
// Пример использования декоратора class Component { operation() { return "Basic Component"; } } class Decorator { constructor(component) { this.component = component; } operation() { return this.component.operation(); } } class ConcreteDecoratorA extends Decorator { operation() { return `ConcreteDecoratorA(${super.operation()})`; } } class ConcreteDecoratorB extends Decorator { operation() { return `ConcreteDecoratorB(${super.operation()})`; } } const simple = new Component(); console.log(simple.operation()); const decoratorA = new ConcreteDecoratorA(simple); console.log(decoratorA.operation()); const decoratorB = new ConcreteDecoratorB(decoratorA); console.log(decoratorB.operation()); -
Модуль (Module): Хотя в Node.js система модулей встроена (CommonJS, ES Modules), паттерн Module pattern в JavaScript (до появления нативных модулей) использовался для создания приватных членов и публичного интерфейса. Это является основой для построения инкапсулированного кода.
Эти паттерны помогали мне создавать более структурированный, масштабируемый и поддерживаемый код.