Clean Code في Swift: المبادئ والأمثلة العملية

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

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

ابدأ الدورة

Clean Code في Swift: المبادئ والأمثلة العملية

\n\n

الكود النظيف (Clean Code) ليس مجرد مصطلح عصري، بل هو مهارة أساسية للمطور المحترف. في نظام Swift البيئي (iOS/macOS)، تؤثر جودة الكود بشكل مباشر على سرعة التطوير، وعدد الأخطاء، وسهولة صيانة المشروع. في هذه المقالة، سنستعرض المبادئ الأساسية لـ Clean Code فيما يتعلق بـ Swift ونعرض تطبيقها بأمثلة عملية.

\n\n

1. التسمية: تحدث بلغة مجال الموضوع

\n\n

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

\n\n

مثال سيء:

\n
func calc(a: [String: Any]) -> Double {\n    var x = 0.0\n    for (_, v) in a {\n        if let n = v as? Double {\n            x += n\n        }\n    }\n    return x\n}
\n\n

مثال جيد (Clean Code):

\n
func calculateTotalPrice(of products: [Product]) -> Double {\n    return products.reduce(0) { $0 + $1.price }\n}
\n\n

مبادئ التسمية في Swift:

\n
    \n
  • الوضوح أهم من الاختصار: remove(at:) أفضل من rem(at:).
  • \n
  • استخدم الأسماء للأنواع: UserViewController، NetworkManager.
  • \n
  • الأفعال للدوال: fetchData()، saveToCache().
  • \n
  • المتغيرات المنطقية: ابدأ بـ is، has، should — isEnabled، hasContent.
  • \n
  • تجنب الاختصارات: backgroundColor بدلاً من bgColor.
  • \n
\n\n

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

\n\n

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

\n\n

انتهاك SRP (ViewController نموذجي):

\n
class ProfileViewController: UIViewController {\n    @IBOutlet weak var nameLabel: UILabel!\n    @IBOutlet weak var avatarImageView: UIImageView!\n    \n    override func viewDidLoad() {\n        super.viewDidLoad()\n        // تحميل البيانات\n        let url = URL(string: "https://api.example.com/user")!\n        let data = try! Data(contentsOf: url)\n        let json = try! JSONSerialization.jsonObject(with: data) as! [String: Any]\n        nameLabel.text = json["name"] as? String\n        \n        // تحميل الصورة الرمزية\n        let imageUrl = URL(string: json["avatar"] as! String)!\n        let imageData = try! Data(contentsOf: imageUrl)\n        avatarImageView.image = UIImage(data: imageData)\n        \n        // حفظ في الكاش\n        UserDefaults.standard.set(json, forKey: "cachedUser")\n    }\n}
\n\n

إعادة الهيكلة مع الالتزام بـ SRP:

\n
// 1. خدمة منفصلة للتعامل مع الشبكة\nclass UserNetworkService {\n    func fetchUser(completion: @escaping (Result<User, Error>) -> Void) {\n        // ... منطق الشبكة\n    }\n}\n\n// 2. مدير كاش منفصل\nclass UserCacheManager {\n    func saveUser(_ user: User) {\n        // ... منطق التخزين المؤقت\n    }\n}\n\n// 3. ViewModel للمنطق التجاري\nclass ProfileViewModel {\n    private let networkService = UserNetworkService()\n    private let cacheManager = UserCacheManager()\n    \n    func loadProfile(completion: @escaping (User) -> Void) {\n        networkService.fetchUser { [weak self] result in\n            switch result {\n            case .success(let user):\n                self?.cacheManager.saveUser(user)\n                completion(user)\n            case .failure:\n                // تحميل من الكاش عند الخطأ\n                if let cachedUser = self?.cacheManager.lo                

المدونات

توصيات الكتب