مبادئ SOLID في Go: النظرية والتطبيق من الألف إلى الياء

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

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

ابدأ الدورة

مبادئ SOLID في Go: النظرية والتطبيق من الألف إلى الياء

\n\n

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

\n\n

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

\n\n

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

\n\n

في Go، غالباً ما يُنتهك هذا المبدأ عندما تقوم بنية (struct) بمهام كثيرة جداً: العمل مع قاعدة البيانات، إرسال البريد الإلكتروني، إنشاء التقارير.

\n\n

مثال سيء (انتهاك SRP):

\n
type User struct {\n    Name  string\n    Email string\n}\n\nfunc (u *User) Save() error {\n    // منطق الحفظ في قاعدة البيانات\n    return nil\n}\n\nfunc (u *User) SendWelcomeEmail() error {\n    // منطق إرسال البريد الإلكتروني\n    return nil\n}\n\nfunc (u *User) GenerateReport() string {\n    // منطق إنشاء التقرير\n    return "report"\n}\n
\n\n

مثال جيد (الالتزام بـ SRP):

\n
type User struct {\n    Name  string\n    Email string\n}\n\ntype UserRepository struct{}\n\nfunc (r *UserRepository) Save(u *User) error {\n    // الحفظ فقط\n    return nil\n}\n\ntype EmailService struct{}\n\nfunc (s *EmailService) SendWelcome(u *User) error {\n    // إرسال البريد الإلكتروني فقط\n    return nil\n}\n\ntype ReportGenerator struct{}\n\nfunc (g *ReportGenerator) Generate(u *User) string {\n    // إنشاء التقرير فقط\n    return "report"\n}\n
\n\n

الخلاصة: كل بنية مسؤولة عن مهمتها الخاصة. تغيير منطق الحفظ لن يؤثر على إرسال البريد الإلكتروني.

\n\n

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

\n\n

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

\n\n

في Go، يتم تنفيذ ذلك بشكل ممتاز من خلال الواجهات (interfaces).

\n\n

مثال سيء (انتهاك OCP):

\n
type PaymentProcessor struct{}\n\nfunc (p *PaymentProcessor) Process(paymentType string, amount float64) {\n    if paymentType == "credit_card" {\n        // منطق لبطاقة الائتمان\n    } else if paymentType == "paypal" {\n        // منطق لـ PayPal\n    }\n    // عند إضافة نوع جديد، يجب تغيير هذه الدالة\n}\n
\n\n

مثال جيد (الالتزام بـ OCP):

\n
type PaymentMethod interface {\n    Pay(amount float64) error\n}\n\ntype CreditCard struct{}\n\nfunc (c *CreditCard) Pay(amount float64) error {\n    // منطق لبطاقة الائتمان\n    return nil\n}\n\ntype PayPal struct{}\n\nfunc (p *PayPal) Pay(amount float64) error {\n    // منطق لـ PayPal\n    return nil\n}\n\nfunc ProcessPayment(method PaymentMethod, amount float64) error {\n    return method.Pay(amount)\n}\n
\n\n

الخلاصة: الآن، لإضافة طريقة دفع جديدة (مثل ApplePay)، يكفي إنشاء بنية جديدة مع دالة Pay()، دون المساس بالكود الموجود.

\n\n

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

\n\n

الجوهر: يجب أن تكون الكائنات في البرنامج قابلة للاستبدال بنسخ من أنواعها الفرعية دون تغيير صحة تنفيذ البرنامج. في Go، هذا يعني أنه إذا كانت دالة تقبل واجهة (interface)، فيجب أن تعمل أي تطبيقية (implementation) لهذه الواجهة بشكل صحيح، دون انتهاك التوقعات.

\n\n

مثال سيء (انتهاك LSP):

\n
type Bird interface {\n    Fly() error\n}\n\nt                

المدونات

توصيات الكتب