Patrons de conception en Swift : de la théorie à la pratique
Les patrons de conception sont des solutions éprouvées pour résoudre des problèmes typiques en développement. Pour un développeur iOS utilisant Swift, maîtriser les patrons n'est pas seulement un atout sur un CV, mais une nécessité. Ils aident à écrire un code propre, réutilisable et testable. Dans cet article, nous allons analyser 5 patrons clés avec des exemples concrets en Swift.
1. Singleton
L'un des patrons les plus populaires en iOS. Il garantit qu'une classe n'a qu'une seule instance et fournit un point d'accès global à celle-ci.
Implémentation en Swift
class NetworkManager { static let shared = NetworkManager() private init() {} // empêche la création d'autres instances
func requestData(from url: URL) { // logique de la requête print("Requête vers \\(url.absoluteString)") }}
// UtilisationNetworkManager.shared.requestData(from: URL(string: "https://api.example.com")!)Quand l'utiliser : pour gérer des ressources partagées (réseau, base de données, UserDefaults). Inconvénient : complique les tests unitaires, il ne faut donc pas en abuser.
2. Factory Method
Définit une interface pour créer un objet, mais permet aux sous-classes de modifier le type de l'objet créé. Idéal lorsqu'on ne sait pas à l'avance quel objet sera nécessaire.
Exemple : création d'éléments d'interface utilisateur
protocol Button { func render()}
class iOSButton: Button { func render() { print("Bouton style iOS") }}
class macOSButton: Button { func render() { print("Bouton style macOS") }}
enum Platform { case iOS, macOS}
class ButtonFactory { static func createButton(for platform: Platform) -> Button { switch platform { case .iOS: return iOSButton() case .macOS: return macOSButton() } }}
// Utilisationlet button = ButtonFactory.createButton(for: .iOS)button.render() // Bouton style iOS3. Observer
Permet aux objets de s'abonner à des événements et de recevoir des notifications en cas de changements. En Swift, il est implémenté nativement via NotificationCenter et Combine.
Exemple avec NotificationCenter
extension Notification.Name { static let userDidLogin = Notification.Name("userDidLogin")}
class AuthManager { func login() { // logique de connexion NotificationCenter.default.post(name: .userDidLogin, object: nil) }}
class ProfileViewController { init() { NotificationCenter.default.addObserver( self, selector: #selector(updateUI), name: .userDidLogin, object: nil ) }
@objc func updateUI() { print("Mise à jour du profil après connexion") }
deinit { NotificationCenter.default.removeObserver(self) }}Alternative moderne : utilisez Combine (iOS 13+) avec @Published et PassthroughSubject pour la programmation réactive.
4. Delegate
L'un des patrons fondamentaux de Cocoa Touch. Il permet à un objet de déléguer l'exécution de tâches à un autre. Largement utilisé dans UIKit (par exemple, UITableViewDelegate).
Création d'un délégué personnalisé
protocol DownloadDelegate: AnyObject { func didFinishDownloading(data: Data) func didFailWithError(error: Error)}
class Downloader { weak var delegate: DownloadDelegate?
func download(from url: URL) { // simulation de téléchargement let data = Data() delegate?.didFinishDownloading(data: data) }}
class ViewController: UIViewController, DownloadDelegate { let downloader = Downloader()
override fu