Какви модели на дизайн сте използвали на практика?
sobes.tech AI
Отговор от AI
На практика съм прилагал следните шаблони за проектиране:
-
Фабричен метод (Factory Method): За създаване на обекти от различни типове без да се указва конкретният клас на създаване. Полезен при работа с различни източници на данни или конфигурации.
// Пример за използване на фабричен метод class DataReader { read() { throw new Error("Методът не е реализиран"); } } class FileReader extends DataReader { read() { console.log("Четене на данни от файл..."); } } class NetworkReader extends DataReader { read() { console.log("Четене на данни от мрежа..."); } } class DataReaderFactory { createReader(type) { switch (type) { case "file": return new FileReader(); case "network": return new NetworkReader(); default: throw new Error("Неизвестен тип на четеца"); } } } 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("Получено обновление:", data); } } const observable = new Observable(); const observer1 = new Observer(); const observer2 = new Observer(); observable.subscribe(observer1); observable.subscribe(observer2); observable.notify("Нови данни налични!"); -
Стратегия (Strategy): За дефиниране на семейство алгоритми, тяхното инкапсулиране и взаимозаменяемост. Позволява алгоритъмът да се променя независимо от клиентите, които го използват. Използва се за различни варианти на обработка на данни или изпълнение на операции.
// Пример за използване на стратегия class PaymentStrategy { pay(amount) { throw new Error("Методът не е реализиран"); } } class CreditCardPayment extends PaymentStrategy { pay(amount) { console.log(`Плащане ${amount} с кредитна карта`); } } class PayPalPayment extends PaymentStrategy { pay(amount) { console.log(`Плащане ${amount} с 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 "Базов компонент"; } } 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 (преди появата на нативните модули) се използваше за създаване на приватни членове и публичен интерфейс. Това е основата за изграждане на инкапсулиран код.
Тези шаблони ми помагаха да създавам по-структуриран, мащабируем и поддържан код.