[iOS] Delegate 패턴이란 무엇일까?

zooneon·2021년 1월 5일
14

Design Pattern

목록 보기
1/2
post-thumbnail

🧐 오늘 알아볼 것은?

오늘은 여러 디자인 패턴 중 Delegate 패턴에 알아보려 한다.
공부를 하던 중 Delegate 패턴을 보게 되었고, 이해가 잘 되지 않던 나는 오기가 생겨 결국.. 폭풍 구글링을 시작하였다.
결국 어찌저찌 이해는 했다.
내가 알아보고 이해한 내용을 정리하기 위해 블로그에 작성하고자 한다.
(만약 잘못된 부분이 있다면 피드백 부탁드립니다. 😇)

✨ Delegate 패턴이 대체 뭐야?

Delegate 패턴은 iOS 개발에서 자주 사용되는 유명한 디자인 패턴이다.
Delegate란 단어는 '위임하다' 라는 사전적 의미를 갖고 있다.
여기서는 '위임자' 라고 생각하면 편할 것 같다.
Delegate 패턴은 delegate, 즉 위임자를 갖고 있는 객체가 다른 객체에게 자신의 일을 위임하는 형태의 디자인 패턴이다.
이렇게 글로 보면 이게 무슨 소리지? 할 것이다. 본인도 그랬다.
그렇다면 예시를 통해 알아보자!

💬 실생활 예시를 통해 알아보기

먼저 예시의 흐름을 설명해보자면,
우리는 파티를 준비하려 한다.
파티를 하기 위해서는 음식과 노래가 필요하다.
파티 책임자는 파티 준비자들에게 음식과 노래를 준비할 것을 주문(위임)한다.
파티 준비자들은 그 주문을 따르고, 각자 다른 음식과 노래를 준비한다.
이것이 전체적인 흐름이고 이제 코드를 살펴보자.

PrepareParty 프로토콜에는 파티를 준비하기 위해 필요한 일들을 작성한다.
우리는 파티를 위해 음식과 노래를 준비할 것이다.

책임자의 역할을 할 PartyDirector 클래스에는 일을 위임할 delegate 변수와 일을 시키는 order() 함수를 만들어준다.
delegate 변수의 자료형으로 PrepareParty 프로토콜을 사용함으로써 이 delegate 변수, 즉 위임자가 파티를 준비하기 위한 일들을 시킬 수 있다.
order() 함수는 delegate 변수를 이용하여 음식과 노래를 준비하는 일을 시킬 것이다.

파티를 준비해 줄 두 명의 고마운 친구들을 만들어주었다.
두 클래스의 특징을 살펴보면 클래스명 뒤에 프로토콜을 명시하여 PrepareParty 프로토콜을 준수하도록 한다.
이를 통해 두 클래스는 파티를 준비하기 위한 일들을 처리한다는 보장을 받는다.
그리고 이니셜라이저 부분을 살펴보면 중요한 코드가 나온다.

이 코드를 우리의 예시를 통해 설명해보자면,
파티 책임자가 시키는 일을 파티 준비자인 자신이 처리하겠다고 명시하는 것이다.
즉, 위임자(여기서는 매개변수로 받은 director)의 delegate 변수를 자신으로 설정함으로써, 자신이 위임자의 일을 대신 처리하겠다는 의미이다.
간단하게 설명하면 위임자의 delegate 변수와 자신을 연결해 주는 코드이다.
이제 의미를 이해했다면 이 코드가 어떻게 가능한지 알아보자.
우리는 우선 delegate 변수를 만들 때 자료형으로 PrepareParty 프로토콜을 설정하였다.
그리고 클래스를 만들 때 PrepareParty 프로토콜을 채택하였는데, 이러면 채택한 프로토콜로 형변환이 가능해진다.
즉, 둘은 같은 자료형이므로 저런 코드가 가능하게 된 것이다.

자 이제 객체를 만들어 코드를 실행해보자.
파티 책임자로 zooneon을 생성하였고, 파티 준비를 도와줄 두 명의 파티 준비자를 각각 생성하였다.
파티 책임자인 zooneon이 일을 주문하면 준비자들은 각각의 일을 처리한다.
여기서 중요한 점은 zooneon이 파티 준비를 시키기만 하였고 어떤 음식, 노래를 준비할 지는 명시하지 않았다.
어떤 것들을 준비할 지는 일을 위임 받은 준비자들이 각자의 방법으로 대신 처리한다.
여기서 Delegate 패턴의 장점이 나오게 되는데,
조금 더 직관적인 프로젝트 예시를 먼저 보고 마지막에 정리하도록 하겠다.

📱 iOS 프로젝트 예시를 통해 알아보기

우리가 볼 예시는 버튼을 클릭하여 UI를 변경하는 간단한 코드이다.

우선 결과물을 보면 이렇다.
이제 코드를 살펴보자!

changeUI() 함수를 갖는 ChangeUIDelegate 프로토콜을 먼저 만들어주었다.
그리고 delegate 변수를 선언해주었는데, 이 변수의 자료형은 ChangeUIDelegate 프로토콜로 선언하였다.
이로써 delegate 변수는 일을 위임할 준비가 되었다.
clickButtonTapped() 메서드에는 Second View에서 Click 버튼을 누를 경우 앞서 선언한 delegate 변수를 통해 위임 받은 객체에서 changeUI() 를 실행하도록 하였다.

First View의 Next 버튼에는 nextButtonTapped() 메서드를 만들어주었다.
nextButtonTapped() 메서드에서는 Second View를 찾아서 보여주고 Second View의 delegate 변수와 연결해주는 코드가 있다.
앞서 설명했듯이, FirstViewController가 ChangeUIDelegate 프로토콜을 채택했기 때문에 형변환이 가능하여 self를 사용하여 연결해주었다.
ChangeUIDelegate를 채택한 FirstViewController에는 위임자가 메서드를 호출하였을 때(위의 경우에서는 Second View에서 Click버튼을 누른 경우) 실행할 changeUI() 함수를 작성해주어야 한다.
이렇게 작성한 함수를 통해 Second View에서 Click 버튼을 눌러 일을 시키면 First View에서 그 일을 대신 수행하는 것이다.
여기서 Second View의 위임자는 일을 시키기만 할 뿐, 어떤 일을 하는지에 대한 구체적인 내용은 모른다.
이것이 Delegate 패턴의 장점이다.
이게 왜 대체 장점인가에 대해서는 Delegate 패턴을 사용하는 이유에서 이야기해보겠다.

💡 Delegate 패턴은 왜 사용할까?

Delegate 패턴을 사용하는 이유는 여러가지 있겠지만, 내 생각은 이렇다.
우선 위에서 내가 말한 장점에 대해 알아보자.
위의 예제들에서 위임자들은 그저 일을 시킬 뿐, 일을 어떻게 처리해야하는지는 모른다.
일을 처리하는 방법은 그 일을 수행하는 객체에 구현되어 있다.
이미 눈치 챈 사람들도 있겠지만, 이렇게 작성하면 코드를 재사용하고 유지보수하기 쉬워진다.
어떤 일을 해야 하는지를 정해놓기만 하고, 상황에 맞는 코드를 작성하면 된다.
예를 들어 우리가 어떤 작업을 처리해야 하는데, 동일한 작업인데도 불구하고 객체마다 다른 내용을 처리해야한다고 생각해보자.
이럴 경우 동일한 작업에 대해서는 함수를 전달하기만 하고, 각각의 내용은 전달 받은 객체에서 처리하기만 하면 된다.
또한 작업을 전달할 때 공통된 부분을 제외하고 처리해야 하는 부분만을 전달하여 처리할 수도 있다.

마치며

열심히 구글링을 하며 찾아보다가 한 블로그에서 이런 문구를 보았다.
"Delegate는 어떤 객체가 해야 하는 일을 부분적으로 확장해서 대신 처리를 한다."
여러 글을 찾아보며 이해하고, 직접 글을 쓰고 난 뒤에 다시 이 문구를 보니 격하게 공감이 됐다.
내가 글에서 설명할 때에도 단순히 사전적 의미인 위임자에 집중하여 설명하였지만, 생각해보면 대신 처리를 하는 것도 맞지만 주어진 일을 확장하기도 한다.
이렇게 생각하니 이해가 더 잘 되는 느낌이다.
분명 내가 작성한 장점 외에 다른 장점들도 있을 것이고, 더 다양하게 활용하는 방법들도 있을 것이다.
앞으로 언제 쓰면 어떤 점에서 어떻게 좋을지 생각하며 적용해봐야겠다.


📚 참고

profile
블로그 이전했습니다. https://blog.zooneon.dev

2개의 댓글

comment-user-thumbnail
2022년 3월 24일

delegate 패턴 아무리 봐도 이해가 안 됐었는데 이 예시 보고 드디어 이해했습니다 감사해요 👍🏻😄

답글 달기
comment-user-thumbnail
2022년 5월 2일

감사합니다. 이해가 잘 되었습니다!

답글 달기