[swift] Swift 업데이트를 통한 디자인 패턴 개선 방법

Swift는 지속적으로 업데이트가 이루어져 개발자들에게 더 나은 개발 경험을 제공합니다. 이러한 업데이트 중에는 디자인 패턴에 대한 개선도 포함되어 있습니다. 디자인 패턴은 소프트웨어 개발에서 동일한 상황에서 발생하는 문제들을 해결하기 위한 일련의 모범 사례입니다. 이번 글에서는 Swift 업데이트를 통해 개선된 디자인 패턴에 대해 알아보겠습니다.

1. MVVM (Model-View-ViewModel)

MVVM은 Model-View-ViewModel의 약자로, Swift에서 데이터 바인딩과 뷰 로직 분리를 간단하게 구현할 수 있는 디자인 패턴입니다. 기존의 MVC(Model-View-Controller) 패턴에서 ViewController가 가지고 있던 역할을 ViewModel이 대신하게 됩니다. 이러한 구조는 코드의 재사용성과 테스트 용이성을 증가시킵니다.

import UIKit

class User {
    var name: String
    var email: String
    
    init(name: String, email: String) {
        self.name = name
        self.email = email
    }
}

class UserViewModel {
    private var user: User

    init(user: User) {
        self.user = user
    }

    var name: String {
        return user.name
    }

    var email: String {
        return user.email
    }
}

class UserViewController: UIViewController {
    @IBOutlet weak var nameLabel: UILabel!
    @IBOutlet weak var emailLabel: UILabel!
    
    var viewModel: UserViewModel?
    
    override func viewDidLoad() {
        super.viewDidLoad()

        nameLabel.text = viewModel?.name
        emailLabel.text = viewModel?.email
    }
}

위 코드에서 UserViewController는 화면의 UI를 관리하며, 화면에 표시될 데이터는 UserViewModel을 통해 제공됩니다. 이렇게 함으로써 로직과 UI가 분리되어 코드의 가독성과 유지보수성이 향상됩니다.

2. Coordinator

Coordinator는 앱의 네비게이션 흐름을 관리하기 위한 디자인 패턴입니다. 기존에는 ViewController가 다른 ViewController로의 네비게이션을 처리했지만, Coordinator를 사용하면 ViewController는 오직 UI 표시에만 전념할 수 있게 됩니다.

import UIKit

protocol Coordinator: AnyObject {
    var navigationController: UINavigationController? { get set }
    
    func start()
    func navigateToNextViewController()
}

class MainCoordinator: Coordinator {
    var navigationController: UINavigationController?
    
    func start() {
        let mainViewController = MainViewController()
        mainViewController.coordinator = self
        navigationController?.pushViewController(mainViewController, animated: true)
    }
    
    func navigateToNextViewController() {
        let nextViewController = NextViewController()
        nextViewController.coordinator = self
        navigationController?.pushViewController(nextViewController, animated: true)
    }
}

class MainViewController: UIViewController {
    weak var coordinator: Coordinator?
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    @IBAction func nextButtonTapped(_ sender: UIButton) {
        coordinator?.navigateToNextViewController()
    }
}

class NextViewController: UIViewController {
    weak var coordinator: Coordinator?
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
}

위 코드에서 Coordinator 프로토콜을 정의하고, MainCoordinator 클래스에서 이 프로토콜을 구현합니다. MainViewControllerNextViewController는 각각의 Coordinator에 대한 참조를 가지고 있으며, 버튼 탭 시 해당 Coordinator의 메서드를 호출하여 다음 뷰로의 네비게이션을 처리합니다.

3. Singleton

Singleton은 앱 전체에서 유일하게 하나의 인스턴스만 생성하여 사용하는 디자인 패턴입니다. Swift에서는 static let을 통해 Singleton을 구현할 수 있습니다.

class UserManager {
    static let shared = UserManager()

    private init() {}

    private var currentUser: User?
    
    func getCurrentUser() -> User? {
        return currentUser
    }
    
    func setUser(user: User) {
        currentUser = user
    }
}

위 코드에서 UserManager 클래스는 shared라는 정적 변수를 통해 하나의 인스턴스만을 생성할 수 있습니다. 이를 통해 여러 곳에서 동일한 인스턴스를 사용하게 되므로 데이터의 일관성과 공유성을 유지할 수 있습니다.

결론

위에서 소개한 MVVM, Coordinator, Singleton 디자인 패턴은 Swift 업데이트를 통해 향상된 디자인 패턴입니다. 이러한 패턴을 활용하면 코드의 가독성, 재사용성, 유지보수성을 개선하여 효율적이고 현대적인 앱을 개발할 수 있습니다. 추가적인 연구와 공부를 통해 더 다양하고 적합한 디자인 패턴을 찾아보세요.