SOLID-Prinzipien in Swift: Theorie und Praxis für fortgeschrittene iOS-Entwickler

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Einleitung: Warum SOLID für Swift-Entwickler wichtig ist

In der Welt der iOS-Entwicklung ist die Erstellung von wartbarem und skalierbarem Code eine zentrale Aufgabe. Die von Robert Martin formulierten SOLID-Prinzipien bleiben der Goldstandard für Softwarearchitektur. Auf fortgeschrittenem Niveau ermöglicht die Beherrschung dieser Prinzipien in Swift nicht nur das Schreiben von sauberem Code, sondern auch den Aufbau flexibler Systeme, die resistent gegen sich ändernde Anforderungen sind. In diesem Artikel analysieren wir jedes Prinzip mit Beispielen in Swift, die auf reale Aufgaben eines iOS/macOS-Entwicklers ausgerichtet sind.



1. Single Responsibility Principle (SRP) in Swift

Theorie: Jede Klasse oder Struktur sollte nur einen Grund für eine Änderung haben. In der Praxis bedeutet dies, dass ein Modul für eine klar definierte Aufgabe verantwortlich ist.



Problem: Überladener ViewController

In UIKit trifft man häufig auf Controller, die gleichzeitig die UI verwalten, Netzwerkanfragen verarbeiten und Daten speichern. Dies verletzt das SRP.

// ❌ Verletzung des SRPclass UserViewController: UIViewController {    @IBOutlet weak var tableView: UITableView!    private var users: [User] = []

override func viewDidLoad() { super.viewDidLoad() fetchUsers() }

private func fetchUsers() { // Netzwerkanfrage URLSession.shared.dataTask(with: URL(string: "https://api.example.com/users")!) { data, _, _ in // JSON-Parsing // Speichern in Core Data DispatchQueue.main.async { self.tableView.reloadData() } }.resume() }}


Lösung: Aufteilung der Verantwortlichkeiten

Die Arbeit mit Daten und dem Netzwerk wird in separate Dienste ausgelagert.

// ✅ SRP: separater Dienst für die Arbeit mit Benutzernprotocol UserServiceProtocol {    func fetchUsers(completion: @escaping (Result<[User], Error>) -> Void)}

class UserService: UserServiceProtocol { func fetchUsers(completion: @escaping (Result<[User], Error>) -> Void) { // Logik der Netzwerkanfrage }}

// ✅ SRP: separater Manager für Core Dataclass CoreDataManager { func saveUsers(_ users: [User]) { // Speichern in Core Data }}

// ✅ SRP: ViewController verwaltet nur die UIclass UserViewController: UIViewController { private let userService: UserServiceProtocol private let coreDataManager: CoreDataManager

init(userService: UserServiceProtocol, coreDataManager: CoreDataManager) { self.userService = userService self.coreDataManager = coreDataManager super.init(nibName: nil, bundle: nil) }

override func viewDidLoad() { super.viewDidLoad() loadUsers() }

private func loadUsers() { userService.fetchUsers { [weak self] result in switch result { case .success(let users): self?.coreDataManager.saveUsers(users) self?.updateUI(with: users) case .failure(let error): self?.showError(error) } } }}


2. Open/Closed Principle (OCP) und Swift-Protokolle

Theorie: Software-Entitäten (Klassen, Module) sollten für Erweiterungen offen, aber für Modifikationen geschlossen sein. In Swift wird dies durch Protokolle und Vererbung erreicht.



Beispiel: Benachrichtigungssystem

// ❌ Verletzung des OCP: Beim Hinzufügen eines neuen Benachrichtigungstyps muss der switch geändert werdenclass NotificationSender {    func send(_ notification: Notification, type: String) {        switch type {        case "email":            // E-Mail senden        case "push":            // Push senden        default:            break        }    }}

// ✅ OCP: Verwendung eines Protokollsprotocol NotificationChannel { func send(_ notification: Notification)}

class EmailChannel: NotificationChannel { func send(_ notification: Notification)

Blogs

Buchempfehlungen