본문 바로가기

디자인 패턴

디자인 패턴 - 대리자 패턴(Delegate Pattern)

안녕하세요.

 

오늘은 디자인 패턴 중 대리자 패턴(Delegate Pattern)에 대해

 

공부해보려고 합니다.

 

대리자 패턴은 UIkit, 애플 프레임워크 등에서 많이 사용되기에

 

제대로 정리를 해 보려고 합니다.

 

 

1. 대리자 패턴(Delegate Pattern)

 

대리자 패턴은 어떠한 객체가 해야 할 일을 다른 객체에게 위임하는 패턴입니다.

 

말 그대로 본인이 아니라 대리자, 즉 다른 객체에게 일을 대신시키는 것입니다.

 

코드를 보면서 이야기해 보겠습니다.

 

class Boss {
	func work {
    	//업무 수행...
    }
}

 

어느 회사에 사장이 있습니다.

 

초기에는 업무의 양이 적기에 사장이 모든 일을 합니다.

 

하지만 회사의 규모가 커지며 사장이 모든 업무를 하기에 벅찹니다.

 

그래서 비서를 고용합니다.

 

class Boss {
	func confirm(_ work: String) {
    	//보고 검토...
    }
}

class Secretary {
	var boss: Boss?

	func checkConfirm(_ work: String) {
    	//사장에게 보고...
        boss?.confirm(work)
    }
}

let boss = Boss()
let secretary = Secretary()

secretary.boss = boss
sercretary.checkConfirm("사장의 컨펌이 필요한 업무")

 

비서는 사장에게 업무 보고를 하고,

 

사장은 컨펌만 합니다.

 

그런데 어느 날 사장은 업무가 더욱 많아져 부사장을 고용하게 됩니다

 

class Boss {
	func confirm(_ work: String) {
    	//보고 검토...
    }
}

class SubBoss {
	func confirm(_ work: String) {
    	//보고 검토...
    }
}

class Secretary {
	var boss: Boss? // error!

	func checkConfirm(_ work: String) {
    	//사장에게 보고...
        boss?.confirm(work)
    }
}

let boss = Boss()
let secretary = Secretary()

secretary.boss = boss
sercretary.checkConfirm("사장의 컨펌이 필요한 업무")

 

부사장 또한 컨펌을 해 줄 수 있음에도 여전히 비서는 사장에게만 보고합니다.

 

그래서 비서에게 사장, 부사장 관계없이 컨펌을 받을 수 있는 사람에게 보고하도록 지시합니다.

 

class Boss: ConfirmDelegate {
	func confirm(_ work: String) {
    	//보고 검토...
    }
}

class SubBoss {
	func confirm(_ work: String) {
    	//보고 검토...
    }
}

class Secretary {
	weak var delegate: ConfirmDelegaet?

	func checkConfirm(_ work: String) {
    	//사장에게 보고...
        boss?.confirm(work)
    }
}

protocol ConfirmDelegate: AnyObject {
    func confirm(_ work: String)
}

let boss = Boss()
let secretary = Secretary()

let boss = Boss()
let subBoss = SubBoss()
let secretary = Secretary()

secretary.delegate = boss
secretary.checkConfirm("컨펌이 필요한 업무")

secretary.delegate = subBoss
secretary.checkConfirm("또 다른 컨펌이 필요한 업무")

 

비서는 상관이 몇 명이 생기든

 

컨펌을 해 줄 수 있는 사람에게 컨펌 요청을 보낼 수 있게 됩니다.

 

여기까지 이해가 잘 되셨나요?

 

 

2. 대리자 패턴(Delegate Pattern)의 사용

그렇다면 왜 대리자 패턴을 사용해야 할까요?

 

 

첫 번째는 단일 책임 원칙(SRP, Single Resposibility Principle)을 지키기 위해서입니다.

 

단일 책임 원칙은 객체 지향 5원칙(SOLID)의 하나로

 

하나의 객체는 하나의 동작의 책임을 가져야 한다는 것입니다.

 

비서는 보고의 업무만, 사장에게는 컨펌의 업무만을 주듯이,

 

한 명에게 하나의 임무를 주는 것입니다.

 

 

두 번째는 객체 간의 결합도를 낮추기 위해서입니다.

 

초기 사장이 비서를 고용했을 때,

 

비서는 사장에게 맞춤 업무를 했습니다.(사장의 객체를 직접 생성)

 

하지만 만약 사장이 바뀐다면 비서의 업무도 수정해줘야 합니다.

 

하지만 대리자 패턴을 사용한다면 사장이 바뀌어도 비서의 업무를 수정해주지 않아도 됩니다.

 

이는 객체 지향 5원칙 중 하나인

 

OCP(Open/Closed Principle)에 해당합니다.

 

확장성은 열려있고 변경에는 닫혀있다는 뜻입니다.

 

 

마지막으로 이벤트 기반 구조를 만들기 위해서 사용합니다.

 

버튼을 눌렀을 때, 

 

위치가 업데이트되었을 때,

 

네트워크 응답이 왔을 때 등

 

어떤 일이 발생했을 때 외부에 알려줘야 하는 상황에서 사용합니다.

 

UIkit를 사용하다 보면 대부분이 Delegate 구조로 되어있습니다.

 

이는 개발자는 요청을 하고, 프레임워크에서는 작업을 해주는 일을 분담해 주기 위해

 

사용한다고 볼 수 있습니다.