아키텍처
아키텍처(Architecture)란?
소프트웨어 아키텍처는 앱의 전체적인 구조를 설계하는 방법이다.
코드가 정리되지 않고 모든 로직이 ViewController에 집중되면 유지보수가 어려움
아키텍처를 적용하면 코드가 모듈화되고 확장성이 좋아짐
아키텍처를 적용하면 좋은 점
코드가 가독성이 높아지고 유지보수가 쉬워짐
앱이 커져도 각 컴포넌트를 쉽게 분리 및 확장 가능
유닛 테스트가 쉬워짐
iOS에서 사용되는 대표적인 아키텍처
MVC (Model-View-Controller) – 기본 아키텍처
iOS에서 기본적으로 제공하는 구조
Model: 데이터 & 비즈니스 로직 관리
View: UI 화면
Controller: View와 Model을 연결하는 역할
문제점
ViewController에 코드가 집중되는 Massive ViewController 문제가 발생할 수 있음
재사용성이 낮고 테스트가 어려움
class UserModel {
var name: String
init(name: String) {
self.name = name
}
}
class ViewController: UIViewController {
var user = UserModel(name: "춘장")
override func viewDidLoad() {
super.viewDidLoad()
print("Hello, \(user.name)!")
}
}
ViewController가 Model과 직접 소통하며 모든 로직을 처리 → 규모가 커질수록 유지보수 어려움
MVP (Model-View-Presenter) – MVC 개선
ViewController에서 로직을 Presenter로 분리하여 관리
Presenter가 View와 Model 간의 중간 다리 역할
장점
ViewController의 역할이 줄어들어 코드가 깔끔해짐
View는 Presenter가 제공하는 데이터만 표시 → 단위 테스트 가능
// Model
struct User {
let name: String
}
// Presenter
class UserPresenter {
private let user = User(name: "메주")
func getUserName() -> String {
return user.name
}
}
// ViewController
class ViewController: UIViewController {
let presenter = UserPresenter()
override func viewDidLoad() {
super.viewDidLoad()
print("Hello, \(presenter.getUserName())!") // Presenter가 데이터 제공
}
}
Presenter가 로직을 처리하고 View는 데이터를 받아서 UI를 업데이트하는 역할만 수행
MVVM (Model-View-ViewModel) – 현재 가장 많이 사용
Apple이 SwiftUI에서 권장하는 아키텍처
ViewModel을 추가하여 데이터를 가공하고 View에 전달
장점
View와 Model이 분리되어 유지보수가 용이
Combine이나 RxSwift와 결합하면 비동기 데이터 바인딩 가능
import Combine
// Model
struct User {
let name: String
}
// ViewModel
class UserViewModel: ObservableObject {
@Published var userName = ""
init() {
let user = User(name: "감태")
userName = user.name
}
}
// View (SwiftUI)
struct ContentView: View {
@StateObject var viewModel = UserViewModel()
var body: some View {
Text("Hello, \(viewModel.userName)!")
}
}
ViewModel이 데이터 가공을 담당하여 View는 UI를 그리는 역할만 수행
디자인 패턴
디자인 패턴(Design Pattern)이란?
디자인 패턴은 소프트웨어에서 자주 등장하는 문제를 해결하는 방법이다.
iOS 개발에서 자주 사용되는 대표적인 디자인 패턴을 소개한다.
대표적인 iOS 디자인 패턴
싱글톤 패턴 (Singleton Pattern) – 앱 내에서 하나의 인스턴스만 유지
앱 내에서 하나의 객체만 존재하도록 보장하는 패턴
ex) UserDefaults, Core Data, APIManager 등
class APIManager {
static let shared = APIManager()
private init() {} // 외부에서 인스턴스 생성 방지
}
주의점
앱 전체에서 상태를 공유하므로 남용하면 유지보수가 어려워질 수 있음
팩토리 패턴 (Factory Pattern) – 객체 생성을 한 곳에서 관리
객체 생성 로직을 분리하여 코드 재사용성을 높임
class User {
let name: String
init(name: String) {
self.name = name
}
}
class UserFactory {
static func createUser(name: String) -> User {
return User(name: name)
}
}
// 사용 예제
let user = UserFactory.createUser(name: "지성")
장점
객체 생성 로직을 캡슐화하여 코드 중복을 줄일 수 있음
옵저버 패턴 (Observer Pattern) – 이벤트 감지 및 반응
한 객체의 상태 변화가 여러 객체에 영향을 미치는 경우 사용
NotificationCenter, Combine, RxSwift에서 활용 가능
NotificationCenter.default.addObserver(self, selector: #selector(handleUpdate), name: .dataUpdated, object: nil)
@objc func handleUpdate() {
print("데이터가 업데이트되었습니다!")
}
장점
비동기 이벤트 처리에 유용
MVVM 패턴과 함께 사용하면 효과적