Clean Architecture(클린 아키텍처)의 개념을 이해했다면, 이제 Swift를 활용하여 실제로 Clean Architecture를 적용하는 예제를 살펴보겠습니다.
Step 1: 프로젝트 설정과 기본 환경 구성
- Xcode를 열고 새로운 프로젝트를 생성합니다.
- "Single View App" 템플릿을 선택하고, 프로젝트 이름을 "CleanArchitectureExample"로 지정합니다.
Step 2: Clean Architecture 디렉토리 구조
- 프로젝트 내에 아래와 같이 Clean Architecture 디렉토리 구조를 만듭니다.
- CleanArchitectureExample
- Entities
- UseCases
- InterfaceAdapters
- Controllers
- Presenters
- FrameworksAndDrivers
Step 3: Entity 구현
- 프로젝트 내에 Todo.swift 파일을 생성합니다.
import Foundation
struct Todo {
let id: UUID
var title: String
var isCompleted: Bool
}
Step 4: Use Case 구현
- 프로젝트 내에 TodoUseCase.swift 파일을 생성합니다.
import Foundation
protocol TodoUseCase {
func fetchTodos() -> [Todo]
func addTodo(title: String)
func toggleCompletion(for todo: Todo)
}
class DefaultTodoUseCase: TodoUseCase {
private var todos: [Todo] = []
func fetchTodos() -> [Todo] {
return todos
}
func addTodo(title: String) {
let todo = Todo(id: UUID(), title: title, isCompleted: false)
todos.append(todo)
}
func toggleCompletion(for todo: Todo) {
if let index = todos.firstIndex(where: { $0.id == todo.id }) {
todos[index].isCompleted.toggle()
}
}
}
Step 5: Interface Adapters 구현
- Controllers 디렉토리에 TodoViewController.swift 파일을 생성합니다.
import UIKit
class TodoViewController: UIViewController {
private let todoUseCase: TodoUseCase
init(todoUseCase: TodoUseCase) {
self.todoUseCase = todoUseCase
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
// View 구현은 생략합니다.
}
}
Presenters 디렉토리에 TodoPresenter.swift 파일을 생성합니다.
import Foundation
protocol TodoPresentable {
func presentTodos(_ todos: [Todo])
}
class TodoPresenter: TodoPresentable {
private weak var viewController: TodoViewController?
init(viewController: TodoViewController) {
self.viewController = viewController
}
func presentTodos(_ todos: [Todo]) {
// View에 Todo 리스트를 표시하는 로직을 작성합니다. (생략)
}
}
Step 6: Frameworks & Drivers 구현
- FrameworksAndDrivers 디렉토리에 TodoFramework.swift 파일을 생성합니다.
import Foundation
class TodoFramework {
static let shared = TodoFramework()
private init() {}
func makeTodoViewController() -> TodoViewController {
let todoUseCase: TodoUseCase = DefaultTodoUseCase()
let todoPresenter: TodoPresenter = TodoPresenter(viewController: viewController)
let viewController = TodoViewController(todoUseCase: todoUseCase)
viewController.presenter = todoPresenter
return viewController
}
}
Step 7: 앱 델리게이트 수정
- AppDelegate.swift 파일을 열고, didFinishLaunchingWithOptions 메서드를 아래와 같이 수정합니다
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
window = UIWindow(frame: UIScreen.main.bounds)
let viewController = TodoFramework.shared.makeTodoViewController()
window?.rootViewController = viewController
window?.makeKeyAndVisible()
return true
}
}
이제 Clean Architecture의 기본적인 구조를 갖춘 예제가 완성되었습니다. Entities, UseCases, InterfaceAdapters, 그리고 Frameworks & Drivers를 독립적으로 구성하여 각각의 책임을 명확히 할당하고, 결합도를 낮추었습니다. 이제 각각의 레이어를 개발하거나 테스트할 때 독립적으로 진행할 수 있게 되었습니다.
추가적으로 UI, 데이터베이스, 네트워크와 같은 외부 환경과의 결합을 InterfaceAdapters 레이어에서 관리하고, UseCase와 Entity는 순수한 비즈니스 로직에 집중할 수 있도록 설계했습니다. 이를 통해 유연하고 테스트 가능한 앱을 만들 수 있게 되었습니다.
이상으로, Swift를 활용하여 구현한 Clean Architecture 예제에 대해 설명드렸습니다. Clean Architecture의 장점을 최대한 활용하여 유지보수성과 확장성이 뛰어난 소프트웨어를 개발할 수 있기를 바랍니다.
'Swift' 카테고리의 다른 글
Swift TCA와 Environment로 앱의 라이프사이클 체크하기 (0) | 2023.07.25 |
---|---|
Swift TCA와 UIKit으로 실시간 검색 앱 만들기 (0) | 2023.07.25 |
Swift TCA와 Swinject를 활용한 Navigation 샘플 만들기 (0) | 2023.07.20 |
TCA와 UIKit을 활용한 DSR 계산기 (0) | 2023.07.20 |
애플세계개발자대회(WWDC) 2023에서 공개된 iOS 17에 대한 새로운 기능들을 소개합니다. (0) | 2023.07.16 |