Delegate패턴과 단일 책임원칙

임혜정·2024년 7월 1일
0

Delegate패턴은 어떤 객체가 다른 객체에 자신의 책임을 위임(delegate)하는 디자인 패턴이다.

UIViewController에서 사용자 인터페이스 이벤트나 데이터 소스와의 상호작용을 처리할 때 이 패턴을 많이 사용하게된다.

그냥 혼자 알아서하지 왜 위임해야하는가?

Delegate 패턴의 이유: 관심사 분리 (Separation of Concerns)

객체가 작업을 다른 객체에 위임하는 중요한 이유 중 하나는 관심사 분리이다. 객체가 각자 특정한 역할만 하게해서 명확성을 높이고 유지보수를 편하게 하기 위함이다.

관심사 분리의 예: UITableView와 Delegate 패턴

UITableView는 많은 데이터 셀을 관리하고 표시하는 역할을 한다. 하지만 각 셀에 표시할 데이터, 셀을 선택했을 때의 동작 등을 UITableView 자체가 모두 갖고있을 필요는 없다.

관심사 분리의 구현

  • UITableView: 데이터 목록을 표시하고 관리하는 역할에만 집중
  • Delegate 및 DataSource: 데이터를 제공하고 사용자 인터랙션에 반응하는 역할을 담당하고 UIViewController가 이러한 역할을 맡게 된다.

예제 코드

import UIKit

// Model: 단순한 데이터 구조
struct Fruit {
    let name: String
}

// View Controller가 DataSource와 Delegate 역할
class FruitTableViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

    var tableView: UITableView!
    var fruits: [Fruit] = [
        Fruit(name: "Apple"),
        Fruit(name: "Banana"),
        Fruit(name: "Cherry")
    ]

    override func viewDidLoad() {
        super.viewDidLoad()

        // 테이블 뷰 초기화 및 설정
        tableView = UITableView(frame: view.bounds)
        tableView.dataSource = self
        tableView.delegate = self
        tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
        
        view.addSubview(tableView)
    }

    // UITableViewDataSource 메서드
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return fruits.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        cell.textLabel?.text = fruits[indexPath.row].name
        return cell
    }

    // UITableViewDelegate 메서드
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        print("Selected fruit: \(fruits[indexPath.row].name)")
    }
}

관심사 분리의 중요성

  1. 단일 책임 원칙 (Single Responsibility Principle):

    • UITableView는 단순히 데이터 목록을 표시하는 뷰 역할만 한다. 데이터가 어떻게 표시되고 사용자 인터랙션이 어떻게 처리되는지는 UITableView가 모름
    • 데이터 소스와 사용자 인터랙션 처리는 UIViewController가 담당한다. 이는 UIViewController가 데이터에 대한 지식을 갖고 있고, 사용자 인터렉션을 처리하는 데 적합하기 때문이다.
  2. 유지보수:

    • UITableView 자체의 변경이 필요할 때/ 데이터 소스나 사용자 인터랙션 처리가 변경될 때를 서로 독립적으로 수정할 수 있다. 그럼 수정해야할 부분이 적어진다.
    • 새로운 데이터를 추가하거나 셀의 레이아웃을 변경하는 작업은 UIViewController에서 처리한다. 그러나 UITableView는 이러한 변경에 영향을 받지 않는다.
  3. 테스트:

    • 각 컴포넌트를 독립적으로 테스트할 수 있다. UITableView는 데이터 소스와 델리게이트 없이도 표시 기능을 테스트할 수 있고, UIViewController는 데이터 제공 및 사용자 인터랙션 처리 로직을 독립적으로 테스트할 수 있다.

정리

UITableView와 UIViewController 간의 역할 분담으로, Delegate 패턴을 사용하면 관심사 분리를 통해 코드가 명확해지고 수정이 쉬워지는 것을 공부해보았다. 이로서 코드의 구조도 개선되고 각 컴포넌트가 자신에게 맞는 역할에만 집중하게 하는 것이다.

profile
오늘 배운걸 까먹었을 미래의 나에게..⭐️

0개의 댓글