Clean Code en Swift : principes et exemples pratiques

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Clean Code en Swift : principes et exemples pratiques

\n\n

Le code propre (Clean Code) n'est pas simplement un terme à la mode, mais une compétence fondamentale pour tout développeur professionnel. Dans l'écosystème Swift (iOS/macOS), la qualité du code influence directement la vitesse de développement, le nombre de bogues et la facilité de maintenance du projet. Dans cet article, nous analyserons les principes clés du Clean Code appliqués à Swift et montrerons leur mise en œuvre à travers des exemples pratiques.

\n\n

1. Nommage : parlez le langage du domaine métier

\n\n

Un bon nom de variable, de fonction ou de classe remplace les commentaires. En Swift, avec son système de types riche et ses valeurs optionnelles, un nommage correct est particulièrement important.

\n\n

Mauvais exemple :

\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

Bon exemple (Clean Code) :

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

Principes de nommage en Swift :

\n
    \n
  • La clarté prime sur la concision : remove(at:) est meilleur que rem(at:).
  • \n
  • Utilisez des noms pour les types : UserViewController, NetworkManager.
  • \n
  • Des verbes pour les fonctions : fetchData(), saveToCache().
  • \n
  • Variables booléennes : commencez par is, has, should — isEnabled, hasContent.
  • \n
  • Évitez les abréviations : backgroundColor au lieu de bgColor.
  • \n
\n\n

2. Principe de responsabilité unique (SRP) en Swift

\n\n

Chaque classe, structure ou fonction doit avoir une seule raison de changer. Dans le développement iOS, cela est particulièrement pertinent pour les ViewController, qui se transforment souvent en "objets divins".

\n\n

Violation du SRP (ViewController typique) :

\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        // Chargement des données\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        // Chargement de l'avatar\n        let imageUrl = URL(string: json["avatar"] as! String)!\n        let imageData = try! Data(contentsOf: imageUrl)\n        avatarImageView.image = UIImage(data: imageData)\n        \n        // Sauvegarde dans le cache\n        UserDefaults.standard.set(json, forKey: "cachedUser")\n    }\n}
\n\n

Refactoring avec respect du SRP :

\n
// 1. Service séparé pour le réseau\nclass UserNetworkService {\n    func fetchUser(completion: @escaping (Result<User, Error>) -> Void) {\n        // ... logique réseau\n    }\n}\n\n// 2. Gestionnaire de cache séparé\nclass UserCacheManager {\n    func saveUser(_ user: User) {\n        // ... logique de mise en cache\n    }\n}\n\n// 3. ViewModel pour la logique métier\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                // Chargement depuis le cache en cas d'erreur\n                if let cachedUser = self?.cacheManager.lo                

Blogs

Book Recommendations