위임 (객체 지향 프로그래밍)

객체 지향 프로그래밍에서 위임(delegation)은 한 객체(수신자)의 멤버(프로퍼티 또는 메서드)를 다른 원래 객체(발신자)의 문맥에서 평가하는 것을 의미한다. 위임은 명시적으로, 즉 발신 객체의 책임을 수신 객체에 전달함으로써 수행될 수 있으며, 이는 모든 객체 지향 언어에서 가능하다. 또는 암시적으로, 언어의 멤버 조회 규칙에 의해 수행될 수 있으며, 이는 기능에 대한 언어 지원을 필요로 한다. 암시적 위임은 프로토타입 기반 프로그래밍에서 동작 재사용의 근본적인 방법이며, 클래스 기반 프로그래밍의 상속에 해당한다. 언어 수준에서 위임을 지원하는 가장 잘 알려진 언어는 Self와 자바스크립트이며, Self는 자체 호출 시 메서드 조회에 사용되는 가변 부모 슬롯 개념을 통해 위임 개념을 통합한다. 자바스크립트 위임을 참조하라.

위임이라는 용어는 객체 간의 다양한 다른 관계에 대해서도 느슨하게 사용된다. 더 자세한 내용은 위임 (프로그래밍)을 참조하라. 흔히 혼동되는 개념은 단순히 다른 객체를 사용하는 것으로, 더 정확하게는 자문 또는 집합이라고 한다. 그리고 한 객체의 멤버를 다른 객체의 해당 멤버를 평가함으로써 평가하는 것으로, 특히 수신 객체의 문맥에서 이루어지는 것을 더 정확하게는 전달이라고 한다(래퍼 객체가 자신을 래핑된 객체에 전달하지 않을 때). 위임 패턴은 위임을 구현하기 위한 소프트웨어 디자인 패턴이지만, 이 용어는 자문 또는 전달을 위해 느슨하게 사용되기도 한다.

개요
이러한 위임의 의미는 소위 자기 호출을 디스패치하기 위한 메서드 조회 규칙을 활용하는 프로그래밍 언어 기능으로, 1986년 리버만이 그의 논문 "객체 지향 시스템에서 공유된 동작을 구현하기 위한 프로토타입 객체 사용(Using Prototypical Objects to Implement Shared Behavior in Object-Oriented Systems)"에서 정의했다.

위임은 동적 바인딩에 의존하는데, 이는 주어진 메서드 호출이 런타임에 다른 코드 세그먼트를 호출할 수 있어야 하기 때문이다. 이는 프로그램 구성 요소의 동작을 사용자 정의하는 수단으로 MacOS(및 그 전신인 NeXTStep) 전반에 걸쳐 사용된다. 이는 단일 OS 제공 클래스를 사용하여 창을 관리하는 구현을 가능하게 하는데, 클래스는 프로그램별 대리자를 받아 필요에 따라 기본 동작을 재정의할 수 있기 때문이다. 예를 들어, 사용자가 닫기 버튼을 클릭하면 창 관리자는 대리자에게 windowShouldClose: 호출을 보내고, 창 내용에 저장되지 않은 데이터가 있는 경우 대리자는 창 닫기를 지연시킬 수 있다.

위임은 자기의 지연 바인딩으로 특징지어질 수 있다(그리고 전달과 구별된다).

즉, 수신 객체의 메서드 정의에 있는 는 정의 시점(예: 컴파일 타임 또는 함수가 객체에 연결될 때)에 해당 객체에 정적으로 바인딩되지 않고, 평가 시점에 원래 객체에 바인딩된다.

일부 경우에는 프로그램 코드를 더 읽기 쉽고 이해하기 쉽게 만들기 위해 상속보다 위임을 선호할 수 있다고 주장되어 왔다. 명시적 위임이 상당히 널리 퍼져 있음에도 불구하고, 상속의 대안 모델로 위임을 구현하는 주요 프로그래밍 언어는 상대적으로 적다. 위임과 상속 사이의 정확한 관계는 복잡하다. 일부 저자는 이들을 동등하다고 보거나, 하나가 다른 하나의 특별한 경우라고 본다.

위임에 대한 언어 지원
메서드 조회 규칙을 통해 위임을 지원하는 언어에서 메서드 디스패치는 상속에서 가상 메서드에 정의된 방식과 동일하게 정의된다. 메서드 조회 중에는 항상 가장 구체적인 메서드가 선택된다. 따라서 위임 링크(객체 참조가 아님)를 통해 다른 객체로 제어권을 전달했더라도 원래 수신자 엔티티가 메서드 조회의 시작점이 된다.

위임은 런타임에 발생할 수 있으며 특정 유형의 엔티티 하위 집합에만 영향을 미치고 런타임에 제거될 수도 있다는 장점이 있다. 반면 상속은 일반적으로 인스턴스보다는 유형을 대상으로 하며 컴파일 타임으로 제한된다. 다른 한편으로 상속은 정적으로 타입 검사가 가능하지만, 위임은 일반적으로 제네릭 없이는 불가능하다(비록 제한된 버전의 위임은 정적으로 타입 안전할 수 있지만). 위임은 "특정 객체를 위한 런타임 상속"이라고 불릴 수 있다.

다음은 C#/자바와 유사한 언어로 작성된 의사코드 예제이다.

class A {
 void foo() {
 // "this"는 다른 언어에서 "current", "me", "self"로도 알려져 있다.
 this.bar();
 }

 void bar() {
 print("a.bar");
 }
}

class B {
 private delegate A a; // 위임 링크

 public B(A a) {
 this.a = a;
 }

 void foo() {
 a.foo(); // a-인스턴스에서 foo() 호출
 }

 void bar() {
 print("b.bar");
 }
}

a = new A();
b = new B(a); // 두 객체 간의 위임 설정

를 호출하면 가 의 문맥 내에서 원래 수신 객체인 를 참조하므로 b.bar가 출력된다. 의 이러한 모호성은 객체 정신분열이라고 불린다.

암시적 를 명시적 매개변수로 번역하면 (에서, 는 대리자) 호출은 메서드 해결을 위해 의 유형을 사용하고, 인수에 대해 위임 객체 를 사용하여 로 번역된다.

상속을 사용하면 유사한 코드(해결이 객체가 아닌 클래스에 기반한다는 것을 강조하기 위해 대문자를 사용)는 다음과 같다.

class A {
 void foo() {
 this.bar();
 }

 void bar() {
 print("A.bar");
 }
}

class B extends A {
 public B() {}

 void foo() {
 super.foo(); // 슈퍼클래스 (A)의 foo() 호출
 }

 void bar() {
 print("B.bar");
 }
}

b = new B();

를 호출하면 B.bar가 출력된다. 이 경우 는 모호하지 않다. 단일 객체 가 있고, 는 서브클래스의 메서드로 해결된다.

일반적으로 프로그래밍 언어는 이 특이한 형태의 위임을 언어 개념으로 지원하지 않지만, 몇 가지 예외가 있다.

이중 상속
언어가 위임과 상속을 모두 지원하는 경우 다음과 같이 두 메커니즘을 동시에 사용하여 이중 상속을 수행할 수 있다.

class C extends A {
 delegationlink D d;
}

이는 메서드 조회에 대한 추가 규칙을 요구하는데, 이제 가장 구체적인 메서드로 지정될 수 있는 두 가지 잠재적 메서드가 있기 때문이다(두 가지 조회 경로 때문에).

관련 분야
위임은 엔티티 간에 코드와 데이터를 공유하기 위한 저수준 메커니즘으로 설명될 수 있다. 따라서 다른 언어 구성의 기초를 형성한다. 특히 역할 지향 프로그래밍 언어는 위임을 활용해 왔지만, 특히 오래된 언어들은 위임을 사용한다고 주장하면서 사실상 애그리게이션을 사용했다. 이것은 속임수로 간주되어서는 안 되며, 단지 위임이 의미하는 바의 복수 정의일 뿐이다(위에서 설명한 바와 같이).

최근에는 위임의 분산에 대한 작업도 이루어졌는데, 예를 들어 검색 엔진(저렴한 호텔 방 찾기)의 클라이언트가 위임을 사용하여 공유된 엔티티를 사용하여 최고의 검색 결과와 일반적인 재사용 가능한 기능을 공유할 수 있다.

위임은 또한 2003년 에른스트와 로렌츠에 의해 관점 지향 프로그래밍의 어드바이스 해결을 위해 제안되었다.

 같이 보기 
 위임 패턴
 어댑터 패턴
 후킹
 연속체
 구현 상속
 상속 의미론
 정신분열 (객체 지향 프로그래밍)
 가상 상속
 래퍼 함수

구분:
 델리게이트 (CLI)
 위임 (프로그래밍)
 객체 집합
 전달 (객체 지향 프로그래밍)

내용주

 각주 

 
 Lynn Andrea Stein, Henry Liberman, David Ungar: A shared view of sharing: The Treaty of Orlando. In: Won Kim, Frederick H. Lochovsky (Eds.): Object-Oriented Concepts, Databases, and Applications ACM Press, New York 1989, ch. 3, pp. 31–48 (online at Citeseer)
 
 Malenfant, J.: On the Semantic Diversity of Delegation-Based Programming Languages, Proceedings of the OOPSLA95, New York: ACM 1995, pp. 215–230.
 
 Kasper Bilsted Graversen: The nature of roles---A taxonomic analysis of roles as a language construct. Ph.D. Thesis 2006, (Online at IT University of Copenhagen)

 외부 링크 
 C++에서 Delegate를 구현하는 새로운 방법
 C++에서 빠른 델리게이트
 PerfectJPattern 오픈 소스 프로젝트, 자바에서 델리게이트의 재사용 가능한 구현 제공

분류:객체 지향 프로그래밍