مبادئ SOLID في TypeScript: النظرية والتطبيق مع أمثلة

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

مقدمة: لماذا SOLID مهم في TypeScript



عند التطوير باستخدام TypeScript، خاصة في المشاريع الكبيرة، يصبح الحفاظ على نقاء ومرونة الكود أمرًا بالغ الأهمية. SOLID هي خمسة مبادئ أساسية للبرمجة كائنية التوجه تساعد في إنشاء تطبيقات قابلة للتوسع والاختبار والصيانة بسهولة. هذه المبادئ ذات صلة خاصة بـ TypeScript، الذي يضيف الكتابة الثابتة والواجهات إلى JavaScript، مما يوفر أدوات قوية لتنفيذها.



في هذه المقالة، سنشرح كل مبدأ من مبادئ SOLID الخمسة من منظور TypeScript، مع دعم النظرية بأمثلة عملية من الكود. ستتعلم كيفية تطبيق هذه المبادئ لتحسين بنية مشاريعك.



1. Single Responsibility Principle (مبدأ المسؤولية الواحدة)



النظرية: يجب أن يكون لكل كلاس أو وحدة سبب واحد فقط للتغيير. بمعنى آخر، يجب أن يكون الكلاس مسؤولاً عن جزء واحد فقط من وظائف البرنامج.



انتهاك المبدأ:



// ❌ سيء: الكلاس مسؤول عن البيانات والحفظ والتنسيق معًاclass User {  constructor(public name: string, public email: string) {}

saveToDatabase(): void { console.log(`حفظ ${this.name} في قاعدة البيانات`); }

generateHTML(): string { return `<div>${this.name} - ${this.email}</div>`; }}


التصحيح بتطبيق SRP:



// ✅ جيد: تقسيم المسؤولية إلى ثلاثة كلاساتclass User {  constructor(public name: string, public email: string) {}}

class UserRepository { save(user: User): void { console.log(`حفظ ${user.name} في قاعدة البيانات`); }}

class UserView { render(user: User): string { return `<div>${user.name} - ${user.email}</div>`; }}


الآن كل كلاس لديه مسؤولية واحدة واضحة، مما يبسط اختبار الكود وتعديله.



2. Open-Closed Principle (مبدأ الانفتاح/الإغلاق)



النظرية: يجب أن تكون الكيانات البرمجية (الكلاسات، الوحدات، الدوال) مفتوحة للتمديد ولكن مغلقة للتعديل. هذا يعني أنه يجب أن تكون قادرًا على إضافة وظائف جديدة دون تغيير الكود الموجود.



انتهاك المبدأ:



// ❌ سيء: عند إضافة نوع جديد من الأشكال، يجب تعديل كلاس AreaCalculatorclass AreaCalculator {  calculate(shape: any): number {    if (shape.type === 'circle') {      return Math.PI * shape.radius ** 2;    } else if (shape.type === 'rectangle') {      return shape.width * shape.height;    }    return 0;  }}


التصحيح بتطبيق OCP:



// ✅ جيد: استخدام واجهة وتعدد الأشكالinterface Shape {  area(): number;}

class Circle implements Shape { constructor(public radius: number) {} area(): number { return Math.PI * this.radius ** 2; }}

class Rectangle implements Shape { constructor(public width: number, public height: number) {} area(): number { return this.width * this.height; }}

class AreaCalculator { calculate(shape: Shape): number { return shape.area(); // مغلق للتعديل، مفتوح للتمديد }}


الآن لإضافة شكل جديد (مثل Triangle)، يكفي إنشاء كلاس جديد ينفذ الواجهة Shape دون تعديل AreaCalculator.



3. Liskov Substitution Principle (مبدأ الاستبدال لباربرا ليسكوف)



النظرية: يجب أن تكون الكائنات في البرنامج قابلة للاستبدال بنماذج من أنواعها الفرعية دون التأثير على صحة البرنامج. إذا كان لديك كلاس أساسي وكلاس وارث، يجب أن يعمل الكود الذي يتعامل مع الكلاس الأساسي بشكل صحيح مع الكلاس الوارث أيضًا.



انتهاك المبدأ:



// ❌ سي                

المدونات

توصيات الكتب