GGURUPiOS

[Swift] Delegate Pattern이란? 왜 사용할까? 본문

Swift/문법 파헤치기

[Swift] Delegate Pattern이란? 왜 사용할까?

꾸럽 2023. 11. 7. 00:30

안녕하세요.

이번시간은 UIKit을 쓰다보면 수없이 마주치게 되는 Delegate Pattern에 대하여 알아보도록 하겠습니다.

UIKit의 텍스트필드, 테이블뷰, 컬렉션뷰 등등 다 델리게이트 패턴으로 구현되어 있는데요.

델리게이트 패턴이 뭔지 알아보고, 왜 사용하는지에 대해까지 알아보도록 할게요

 


Delegate Pattern?

위에서 말했듯이, 델리게이트 패턴은 Apple 프레임워크에서 일반적으로 사용되는 디자인 패턴입니다.

스위프트 랭귀지 가이드에 보면 Delegation에 대해 아래와 같이 기술되어 있습니다.

더보기

Delegation is a design pattern that enables a class or structure to hand off (ordelegate) some of its responsibilities to an instance of another type. This design pattern is implemented by defining a protocol that encapsulates the delegated responsibilities, such that a conforming type (known as a delegate) is guaranteed to provide the functionality that has been delegated. Delegation can be used to respond to a particular action, or to retrieve data from an external source without needing to know the underlying type of that source.

  • Delegation은 클래스나 구조체가 자신의 책임 중 일부를 다른 타입의 인스턴스에 넘기거나 위임 할 수 있도록 하는 디자인 패턴
  • 위임된 책임캡슐화 하는 프로토콜을 정의하여 구현
  • 이를 통해 위임된 해당 타입이 위임된 기능을 제공하도록 보장

 


간단한 예제를 만들어 보도록 하겠습니다.

간단한 게임이라고 가정하고, 에너지를 회복시키는 코드를 간단히 만들어 봤습니다

  • Protocol (Delegate): 에너지가 회복됐을 때를 알려주는 메서드 정의
  • 인스턴스 A (EnergyManager): 에너지 회복을 담당하는 클래스
  • 인스턴스 B (ViewController): 위임된 기능을 제공하는 클래스 (아래 코드에서는 단순 출력만 함)

코드 설명을 해보겠습니다.

 

프로토콜에서는 didRestoreEnergy 함수를 통해 에너지가 value만큼 회복됐음을 알려주고 있습니다. 

 

EnergyManager 클래스(인스턴스 A)는 에너지를 회복시키는 역할을 하는 클래스입니다.

에너지드링크를 먹으면 10의 에너지가 올라가는 메서드

진통제를 먹으면 20의 에너지가 올라가는 메서드

또한 최대 에너지인 100을 넘어가면 먹어도 아무 반응이 없게 막아놨습니다. 

간단한 코드입니다. 

 

가드문을 통과하면 EnergyManager클래스는 energy를 증가시키는 역할만 합니다.

나머지 책임은 delegate에게 위임했습니다.

(view를 업데이트 하거나, 화면에 출력 시키는 역할을 이 EnergyManager 클래스가 할 필요가 없습니다.)

 

뷰컨트롤러에서는 일단 IBAction을 통해 진통제, 에너지드링크를 버튼으로 간단히 구현해놨으며

energyManager의 take....()함수들을 통해 EnergyManager 인스턴스 에게 전달합니다.

 

EnergyDelegate를 채택한 뒤, didRestoreEnergy를 구현 해줍니다.

지금은 간단한 예제라 출력만 했지만, View를 업데이트하거나 다른 비지니스로직을 태우겠죠? 

 

EnergyManager의 delegate로 뷰컨 자신을 할당합니다(위임 받습니다)

시뮬레이터로 확인하면 정상적으로 동작합니다. 


간단한 예제를 직접 만들어보며 느낀점 

위임이라는 개념에 대해 좀 더 전반적으로 이해할 수 있었습니다.

 

책임 분리도 잘 할 수 있다는걸 알았습니다.

Manager는 에너지 관리만 하면되고

VIewController는 에너지가 회복된걸 유저에게 알려주기만 하면 됩니다. 

 

그리고 랭귀지 가이드에도 나와있듯, 프로토콜로 캡슐화 한다고 하는데 무슨 뜻인지 처음에는 잘 몰랐습니다.

 

위의 예제에서 ViewController(인스턴스 B)는

Manager(인스턴스 A)의 takePainKiller나 takeEnergyDrink함수의 내부구현을 알아야 할까요?

몰라도 구현에 문제가 없습니다. 문제가 없기보다 알 필요가 없습니다.

상호작용을 할 뿐 입니다.

 

델리게이트(프로토콜)을 통해 캡슐화할 수 있던 것입니다. 이제 이해가 갑니다.  

 

마찬가지로 우리가 UITextField나 UITableView 를 Delegate Pattern으로 구현할 때

내부에 있는 코드를 알아야 할까요? (알수도 없을 뿐더러, 알 필요가 없습니다)

 

유저가 스크롤하고, 유저가 텍스트필드에 입력을 하는 이런 시점을 어떻게 알고 델리게이트의 메서드를 호출하는지

뷰컨트롤러 입장에서 텍스트필드의 구현된 코드를 알아야 할까요???

아니라는 겁니다. 

 

단순히 뷰컨트롤러가 책임을 위임받고, 뷰컨트롤러에서 할 수 있는 일을 구현하면 됩니다.

텍스트필드가 눌렸다거나, 사용자가 입력했다거나 이런 시점을 알 수 있는 코드는 애플이 다 구현해놨습니다.

 

우리는 단순히 잘 만들어놓은 기능을 잘 쓰기만 하면 됩니다!

 

 


출처

 

https://docs.swift.org/swift-book/documentation/the-swift-programming-language/protocols/#Delegation

 

Documentation

 

docs.swift.org