أنماط التصميم في JavaScript: المستوى المتقدم مع أمثلة على Node.js
أنماط التصميم هي حلول معمارية مجربة للمشكلات النمطية. إذا كنت على دراية بالأنماط الأساسية (Singleton، Factory، Observer)، فقد حان الوقت للتعمق في تركيبات أكثر تعقيدًا. في هذه المقالة، سنشرح أربعة أنماط متقدمة من GoF مع أمثلة بلغة JavaScript (Node.js): Composite، Chain of Responsibility، State و Memento. ستساعدك هذه الأنماط على كتابة كود مرن وقابل للتوسع والصيانة.
1. Composite
الغرض: يسمح بتجميع الكائنات في هيكل شجري والعمل مع كل كائن أو مجموعة بشكل موحد.
مثال: نظام ملفات حيث يمكن للمجلد أن يحتوي على ملفات ومجلدات أخرى. نريد حساب الحجم الإجمالي.
// Компонентclass FileSystemComponent { getSize() { throw new Error('Метод getSize() должен быть реализован'); }}
// Листclass File extends FileSystemComponent { constructor(name, size) { super(); this.name = name; this.size = size; }
getSize() { return this.size; }}
// Контейнер (узел)class Folder extends FileSystemComponent { constructor(name) { super(); this.name = name; this.children = []; }
add(component) { this.children.push(component); }
getSize() { return this.children.reduce((total, child) => total + child.getSize(), 0); }}
// Использованиеconst root = new Folder('root');const src = new Folder('src');const index = new File('index.js', 500);const utils = new File('utils.js', 300);
src.add(index);src.add(utils);root.add(src);root.add(new File('package.json', 200));
console.log(`Общий размер: ${root.getSize()} байт`); // 1000 байтالمزايا: يبسط العمل مع الأشجار، ويخفي تعقيد التسلسل الهرمي عن العميل.
2. Chain of Responsibility
الغرض: يسمح بتمرير الطلب عبر سلسلة من المعالجات حتى يقوم أحدهم بمعالجته.
مثال: معالجة طلبات HTTP في Express.js (middleware).
class Handler { setNext(handler) { this.next = handler; return handler; }
handle(request) { if (this.next) { return this.next.handle(request); } return null; }}
class AuthHandler extends Handler { handle(request) { if (!request.token) { return 'Ошибка: неавторизован'; } console.log('AuthHandler: проверка пройдена'); return super.handle(request); }}
class RoleHandler extends Handler { handle(request) { if (request.role !== 'admin') { return 'Ошибка: недостаточно прав'; } console.log('RoleHandler: роль подтверждена'); return super.handle(request); }}
class LoggingHandler extends Handler { handle(request) { console.log(`LoggingHandler: запрос от ${request.user}`); return super.handle(request); }}
// Сборка цепочкиconst auth = new AuthHandler();const role = new RoleHandler();const log = new LoggingHandler();auth.setNext(role).setNext(log);
const request = { token: 'abc123', role: 'admin', user: 'Ivan' };const result = auth.handle(request);console.log(result); // null (все ок)
const badRequest = { token: 'abc123', role: 'user', user: 'Petr' };console.log(auth.handle(badRequest)); // 'Ошибка: недостаточно прав'المزايا: يقلل من الاقتران، ويسهل إضافة/إزالة المعالجات.
3. State
الغرض: يسمح للكائن بتغيير سلوكه اعتمادًا على حالته الداخلية.
مثال: مستند بحالات: مسودة، قيد المراجعة، منشور.
class Docu