Modèles de conception avancés en Swift : de la théorie à la pratique
Les modèles de conception ne sont pas seulement des concepts abstraits, mais des solutions éprouvées par le temps pour des problèmes typiques. Si vous maîtrisez déjà les modèles de base (Singleton, Delegate, MVC) et travaillez sur des applications iOS/macOS complexes, il est temps de passer au niveau supérieur. Dans cet article, nous allons analyser quatre modèles avancés : Builder, Strategy, Observer (via Combine) et Coordinator. Chaque modèle sera illustré par du code Swift réel et des conseils pour l'intégration dans des projets existants.
1. Builder — configuration flexible d'objets complexes
Le modèle Builder est idéal pour créer des objets avec de nombreux paramètres optionnels. Au lieu de longs initialisateurs avec des dizaines de paramètres, vous utilisez une construction étape par étape.
Exemple : configuration de UIAlertController
class AlertBuilder { private var title: String? private var message: String? private var actions: [UIAlertAction] = [] private var preferredStyle: UIAlertController.Style = .alert
func setTitle(_ title: String) -> AlertBuilder { self.title = title return self }
func setMessage(_ message: String) -> AlertBuilder { self.message = message return self }
func addAction(title: String, style: UIAlertAction.Style = .default, handler: ((UIAlertAction) -> Void)? = nil) -> AlertBuilder { let action = UIAlertAction(title: title, style: style, handler: handler) actions.append(action) return self }
func setStyle(_ style: UIAlertController.Style) -> AlertBuilder { self.preferredStyle = style return self }
func build() -> UIAlertController { let alert = UIAlertController(title: title, message: message, preferredStyle: preferredStyle) actions.forEach { alert.addAction($0) } return alert }}
// Utilisationlet alert = AlertBuilder() .setTitle("Erreur") .setMessage("Impossible de charger les données") .addAction(title: "OK", style: .default) .addAction(title: "Réessayer", style: .cancel) .build()present(alert, animated: true)Quand l'utiliser : lors de la création de configurateurs, de ViewController complexes ou de modèles de données avec un grand nombre d'options.
2. Strategy — changement d'algorithmes à la volée
Le modèle Strategy permet d'isoler une famille d'algorithmes et de les rendre interchangeables. C'est particulièrement utile pour le traitement des paiements, la validation des données ou le rendu.
Exemple : système de filtrage de contenu
protocol FilterStrategy { func apply(to items: [String]) -> [String]}
class AlphabeticalFilter: FilterStrategy { func apply(to items: [String]) -> [String] { return items.sorted() }}
class LengthFilter: FilterStrategy { func apply(to items: [String]) -> [String] { return items.filter { $0.count > 5 } }}
class ContentManager { private var strategy: FilterStrategy
init(strategy: FilterStrategy) { self.strategy = strategy }
func setStrategy(_ strategy: FilterStrategy) { self.strategy = strategy }
func filter(items: [String]) -> [String] { return strategy.apply(to: items) }}
// Utilisationlet manager = ContentManager(strategy: AlphabeticalFilter())let data = ["Swift", "Objective-C", "Kotlin", "Java", "Python"]print(manager.filter(items: data)) // ["Java", "Kotlin", "Objective-C", "Python", "Swift"]
manager.setStrategy(LengthFilter())print(manager.filter(items: data)) // ["Objective-C", "Python"]Conseil : combinez Strategy avec une méthode factory pour choisir la stratégie en fonction des préférences de l'utilisateur.