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

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

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

ابدأ الدورة

مقدمة: لماذا تعتبر مبادئ SOLID أساس الكود عالي الجودة في Swift

يواجه كل مطور iOS/macOS عاجلاً أم آجلاً موقفاً يصبح فيه الكود "معكرونة": التغييرات في مكان واحد تكسر التطبيق بأكمله، ويتحول الاختبار إلى كابوس. هنا تأتي مبادئ SOLID للإنقاذ - خمس قواعد أساسية للتصميم كائني التوجه صاغها روبرت مارتن.

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



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

النظرية

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



انتهاك SRP (كود سيء)

class UserManager {    func createUser(name: String, email: String) {        // إنشاء المستخدم        saveToDatabase(user: User(name: name, email: email))        sendWelcomeEmail(to: email)        logEvent("User created: \\(name)")    }        private func saveToDatabase(user: User) { /* ... */ }    private func sendWelcomeEmail(to email: String) { /* ... */ }    private func logEvent(_ message: String) { /* ... */ }}

هنا UserManager مسؤول عن الإنشاء والحفظ وإرسال البريد الإلكتروني والتسجيل - أربعة أسباب للتغيير.



التصحيح (كود جيد)

class UserService {    private let repository: UserRepository    private let emailService: EmailService    private let logger: Logger        init(repository: UserRepository, emailService: EmailService, logger: Logger) {        self.repository = repository        self.emailService = emailService        self.logger = logger    }        func createUser(name: String, email: String) {        let user = User(name: name, email: email)        repository.save(user)        emailService.sendWelcome(to: email)        logger.log("User created: \\(name)")    }}

class UserRepository { func save(_ user: User) { /* حفظ فقط */ }}class EmailService { func sendWelcome(to email: String) { /* إرسال فقط */ }}class Logger { func log(_ message: String) { /* تسجيل فقط */ }}

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



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

النظرية

يجب أن تكون الفصول مفتوحة للتمديد ولكن مغلقة للتعديل. نضيف وظائف جديدة من خلال الوراثة أو البروتوكولات، دون لمس الكود الموجود.



انتهاك OCP

class PaymentProcessor {    func process(payment: Any, type: String) {        if type == "card" {            // معالجة البطاقة        } else if type == "paypal" {            // معالجة PayPal        } // عند إضافة نوع جديد - نغير هذا الفصل    }}


التصحيح باستخدام البروتوكولات

protocol PaymentMethod {    func process(amount: Double)}

class CardPayment: PaymentMethod { func process(amount: Double) { /* معالجة البطاقة */ }}

class PayPalPayment: PaymentMethod { func process(amount: Double) { /* معالجة PayPal */ }}

class PaymentProcessor { func process(payment: PaymentMethod, amount: Double) { payment.process(amount: amount) }}

// إضافة نوع جديد دون تغيير الكود الموجودclass ApplePayPayment: PaymentMethod { func process(amount: Double) { /* معالجة Apple Pay */ }}

الآن لإضافة طريقة دفع جديدة، يكفي إنشاء فصل جديد يطبق بروتوكول PaymentMethod.



3.

المدونات

توصيات الكتب