عند إنشاء أنظمة برمجية، من الضروري إدارة تعقيد قاعدة التعليمات البرمجية.
يناقش الفصل 11 من Clean Code تصميم أنظمة معيارية يسهل صيانتها وتكيفها مع مرور الوقت.
يمكننا استخدام أمثلة جافا سكريبت لتوضيح هذه المفاهيم.
مع نمو الأنظمة، فإنها بطبيعة الحال تصبح أكثر تعقيدًا. هذا التعقيد يمكن أن يجعل من الصعب:
يجب أن يكون النظام المصمم جيدًا سهل التعديل وقابل للاختبار وقابل للتطوير. يكمن سر تحقيق ذلك في الوحدة والفصل الدقيق بين الاهتمامات.
يقع مبدأ النمطية في قلب تصميم الأنظمة النظيفة. يمكنك جعل النظام أكثر قابلية للإدارة عن طريق تقسيم نظام كبير إلى وحدات أصغر مستقلة، ولكل منها مسؤولية واضحة.
يجب أن تحتوي كل وحدة على وظيفة محددة، مما يجعل النظام العام أسهل في الفهم والتغيير.
مثال: تنظيم نظام سلة التسوق
دعونا نتخيل نظام عربة التسوق في جافا سكريبت. بدلاً من تجميع كل المنطق في ملف واحد، يمكنك تقسيم النظام إلى عدة وحدات:
// cart.js export class Cart { constructor() { this.items = []; } addItem(item) { this.items.push(item); } getTotal() { return this.items.reduce((total, item) => total item.price, 0); } } // item.js export class Item { constructor(name, price) { this.name = name; this.price = price; } } // order.js import { Cart } from './cart.js'; import { Item } from './item.js'; const cart = new Cart(); cart.addItem(new Item('Laptop', 1000)); cart.addItem(new Item('Mouse', 25)); console.log(`Total: $${cart.getTotal()}`);
تنقسم المسؤوليات هنا: تدير سلة التسوق العناصر، ويمثل العنصر منتجًا، ويقوم order.js بتنسيق التفاعلات.
يضمن هذا الفصل أن كل وحدة مستقلة بذاتها وأسهل في الاختبار والتغيير بشكل مستقل.
أحد أهداف النمطية هو التغليف - إخفاء الأعمال الداخلية للوحدة النمطية عن بقية النظام.
يجب أن يتفاعل الكود الخارجي مع الوحدة فقط من خلال واجهته المحددة جيدًا.
وهذا يجعل تغيير التنفيذ الداخلي للوحدة أسهل دون التأثير على أجزاء أخرى من النظام.
مثال: تغليف منطق سلة التسوق
لنفترض أننا نريد تغيير كيفية حساب الإجمالي في سلة التسوق. ربما نحتاج الآن إلى حساب ضريبة المبيعات. يمكننا تغليف هذا المنطق داخل فئة Cart:
// cart.js export class Cart { constructor(taxRate) { this.items = []; this.taxRate = taxRate; } addItem(item) { this.items.push(item); } getTotal() { const total = this.items.reduce((sum, item) => sum item.price, 0); return total total * this.taxRate; } } // Now, the rest of the system does not need to know about tax calculations.
لا تتأثر الأجزاء الأخرى من النظام (مثل order.js) بالتغييرات في كيفية حساب الإجمالي. وهذا يجعل نظامك أكثر مرونة وأسهل في الصيانة.
من المشاكل الشائعة في الأنظمة الكبيرة تشابك أجزاء مختلفة من النظام.
عندما تبدأ الوحدة في تحمل الكثير من المسؤوليات، يصبح من الصعب تغييرها أو إعادة استخدامها في سياقات مختلفة.
يضمن مبدأ فصل الاهتمامات أن كل وحدة لديها مسؤولية محددة واحدة.
مثال: التعامل مع الدفع بشكل منفصل
في مثال سلة التسوق، يجب التعامل مع معالجة الدفع في وحدة منفصلة:
// payment.js export class Payment { static process(cart) { const total = cart.getTotal(); console.log(`Processing payment of $${total}`); // Payment logic goes here } } // order.js import { Cart } from './cart.js'; import { Payment } from './payment.js'; const cart = new Cart(0.07); // 7% tax rate cart.addItem(new Item('Laptop', 1000)); cart.addItem(new Item('Mouse', 25)); Payment.process(cart);
الآن، تم فصل منطق الدفع عن إدارة سلة التسوق. وهذا يجعل من السهل تعديل عملية الدفع لاحقًا (على سبيل المثال، التكامل مع مزود دفع مختلف) دون التأثير على بقية النظام.
واحدة من أعظم فوائد النمطية هي أنه يمكنك اختبار كل وحدة بشكل مستقل.
في المثال أعلاه، يمكنك كتابة اختبارات الوحدة لفئة سلة التسوق دون الحاجة إلى القلق بشأن كيفية معالجة الدفعات.
مثال: وحدة اختبار العربة
// cart.test.js import { Cart } from './cart.js'; import { Item } from './item.js'; test('calculates total with tax', () => { const cart = new Cart(0.05); // 5% tax cart.addItem(new Item('Book', 20)); expect(cart.getTotal()).toBe(21); });
مع الفصل الواضح بين الاهتمامات، يمكن اختبار كل وحدة على حدة، مما يجعل تصحيح الأخطاء أسهل والتطوير بشكل أسرع.
عندما تعتمد الوحدات بشكل كبير على بعضها البعض، فإن التغييرات في جزء واحد من النظام يمكن أن يكون لها عواقب غير متوقعة في مكان آخر.
لتقليل ذلك، اهدف إلى الاقتران غير المحكم بين الوحدات.
يسمح هذا لكل وحدة بالتطور بشكل مستقل.
مثال: إدخال التبعيات
بدلاً من اعتماديات التشفير داخل الوحدة، قم بتمريرها كوسائط:
// cart.js export class Cart { constructor(taxRateCalculator) { this.items = []; this.taxRateCalculator = taxRateCalculator; } addItem(item) { this.items.push(item); } getTotal() { const total = this.items.reduce((sum, item) => sum item.price, 0); return total this.taxRateCalculator(total); } }
يجعل هذا الأسلوب فئة سلة التسوق أكثر مرونة وأسهل في الاختبار باستخدام حسابات ضريبية مختلفة.
برمجة سعيدة! ?
تنصل: جميع الموارد المقدمة هي جزئيًا من الإنترنت. إذا كان هناك أي انتهاك لحقوق الطبع والنشر الخاصة بك أو الحقوق والمصالح الأخرى، فيرجى توضيح الأسباب التفصيلية وتقديم دليل على حقوق الطبع والنشر أو الحقوق والمصالح ثم إرسالها إلى البريد الإلكتروني: [email protected]. سوف نتعامل مع الأمر لك في أقرب وقت ممكن.
Copyright© 2022 湘ICP备2022001581号-3