클래스에 대해 기능을 확장하는 두가지 방법중 하나이다. 하나는 상속이고 하나는 위임(Delegation) 이다. 상속을 하지 않아도 해당 클래스의 기능을 확장시킬 수 있는 방법이 된다.
또한, 클래스 하나가 방대해질때, 적절하게 그 클래스의 책임을 다른 클래스들에게 위임해주는 것은 Refactoring 의 방법이 된다.
ObjectOrientedProgramming 을 할때 자주 쓰이는 코딩 스타일. 아마 사람들이 무의식중에 자주 쓸 것이다.
example) 예전에 VonNeumannAirport 을 JuNe 과 1002 가 Pair 하던중 JuNe 이 작성했던 Refactoring 으로서의 Delegation.
~cpp public class Airport { private int _traffic; private int [] _arrivalGate; private int [] _departureGate; private PassengerSet psg; public int getTraffic() { ListIterator iter = psg.passengers.listIterator(); int [] passenger; while (iter.hasNext()) { passenger = (int [])iter.next(); movePassenger(passenger[0], passenger[1], passenger[2]); } return _traffic; } public void setArrivalGates(int [] aCity) { _arrivalGate = aCity; } public void setDepartureGates(int [] aCity) { _departureGate = aCity; } public int [] getArrivalGates() { return _arrivalGate; } public int [] getDepartureGates() { return _departureGate; } public int getDistance(int fromCity, int toCity){ int distance=java.lang.Math.abs(_getArrivalCityGate(fromCity) -_getDepartureCityGate(toCity))+1; return distance; } private void movePassenger(int fromCity, int toCity, int aNumber) { _traffic+=getDistance(fromCity,toCity)*aNumber; } public void setPassengers(PassengerSet psg) { this.psg=psg; } }여기까지는 Airport 이다. 하지만 VonNeumannAirport 문제에서도 보듯, 실제 Input 에 대해서 Configuration 은 여러 Set 이 나온다.
이 기능을 추가하기 위해 일단 Airport Code 를 Refactoring 하기로 했다. 이를 위해 Airport 의 기능중 Configuration 과 관련된 기능에 대해 Configuration 을 Extract 하고, 내부적으로는 Delegation 함으로서 외부적으로 보이는 기능에 대해서는 일관성을 유지한다. (Test Code 가 일종의 Guard 역할을 했었음)
~cpp import java.util.ListIterator; class Configuration { private int [] _arrivalGate; private int [] _departureGate; private int id; public void setArrivalGates(int [] aCity) { _arrivalGate=aCity; } public void setDepartureGates(int [] aCity) { _departureGate=aCity; } public int [] getArrivalGates() { return _arrivalGate; } public int [] getDepartureGates() { return _departureGate; } public int getDistance(int fromCity, int toCity){ int distance=java.lang.Math.abs(_getArrivalCityGate(fromCity) -_getDepartureCityGate(toCity))+1; return distance; } public int _findInIntArray(int anInt,int [] anArray) { for (int i=0;i<anArray.length;i++) { if (anArray[i] == anInt) return i+1; } return -1; } public int _getArrivalCityGate(int aCity) { return _findInIntArray(aCity,getArrivalGates()); } public int _getDepartureCityGate(int aCity) { return _findInIntArray(aCity,getDepartureGates()); } public int getId() { return id; } public void setId(int anId) { id=anId; } } public class Airport { private int _traffic; private int [] _arrivalGate; private int [] _departureGate; private PassengerSet psg; private Configuration conf=new Configuration(); public int getTraffic() { ListIterator iter = psg.passengers.listIterator(); int [] passenger; while (iter.hasNext()) { passenger = (int [])iter.next(); movePassenger(passenger[0], passenger[1], passenger[2]); } return _traffic; } public void setArrivalGates(int [] aCity) { conf.setArrivalGates(aCity); } public void setDepartureGates(int [] aCity) { conf.setDepartureGates(aCity); } public int [] getArrivalGates() { return conf.getArrivalGates(); } public int [] getDepartureGates() { return conf.getDepartureGates(); } public int getDistance(int fromCity, int toCity){ return conf.getDistance(fromCity,toCity); } private void movePassenger(int fromCity, int toCity, int aNumber) { _traffic+=getDistance(fromCity,toCity)*aNumber; } public void setPassengers(PassengerSet psg) { this.psg=psg; } }
DelegationPattern을 쓸 때 중요한 점은, DelegationPattern을 사용하는 클래스의 클라이언트는 그 클래스가 Delegation을 쓰는지 안쓰는지 몰라야 한다는 것이다. 즉, 우리에게 있어 DelegationPattern이 사용된 클래스는 여느 클래스와 동일하게 인식되고 사용되어져야 한다. 게을러서 남에게 자신의 숙제를 위임하는 학생은 절대 남들에게 그 사실을 노출해선 안된다.
ResponsibilityDrivenDesign , Refactoring, DelegationPattern 을 꾸준히 지켜주면 좋은 코드가 나올 수 있다. (DesignPattern 이 유도되어짐)
전에 SE 수업중에 컴포넌트모델의 필요성을 이야기하던중 '상속으로의 재사용이 어렵기 때문에' 이야기를 하셨는데, 왜 대안 중 하나로서의 Delegation 에 대한 언급이 전혀 없으셨는지 모르겠다. Delegation 만 잘 이해해도 준 컴포넌트 스타일의 모듈화 프로그래밍을 잘 진행할 수 있고, 사람들 간의 작업분담도 잘 이끌어 낼 수 있을건데.. --1002