== Pluggable Selector == 가장 간단하게 Pluggable Behavior를 구현하는 방법은 실행될 행동을 저장해놓는 것이다. 먼저 이것의 반례, 즉 서브클래싱 한것을 보자. {{{~cpp class ListPane { public: Type printElement(Object& anObject) { return anObject.printString(); } }; class DollarListPane : public ListPane { public: Type printElement(Object& anObject) { return anObject.asDollarFormatString(); } }; class DiscriptionListPane : public ListPane { public: Type printElement(Object& anObject) { return anObject.desription(); } }; }}} ---- 이런식으로 하나의 메소드만 계속 오버라이딩한다면 서브클래스들의 가치가 없을것 같다. 쉬운 해결책은 ListPane 스스로를 좀 더 유연하게 만드는 것이다. 다른 인스턴스들이 다른 메세지를 보내게 하는 것이다. {{{~cpp class ListPane { private: void (ListPane::*printMessage)(); public: Type printElement(Object& anObject) { return anObject.perform(printMessage); } void initialize() { printMessage = printString; // printString은 어딘가에 구현되어 있다. } }; }}} 가독성 : 그냥 서브클래싱한것보다 떨어진다. 유연성 : P.S는 수신 객체에 구현되어야 한다. 확장성 : 한 오브젝트마다 최대 두번까지만 쓰자. 더 많이 쓰면 프로그램의 의도가 흐려진다. 더 많이 쓰고 싶으면 State Object를 쓰는 법이 있다. ---- 실행될 selector를 가지는 변수를 추가한다. 이름 뒤에 Message를 덧붙인다. selector를 실행하기 쉽게 해주는 Composed Method를 만든다. ---- 예를 들어, 어떤 비쥬얼한 컴포넌트를 다른 것의 상대적인 부분에 위치시키고 싶다면, 상대적인 위치를 만들어주는 Pluggable Selector를 사용할 수 있다.(???) {{{~cpp class RelativePoint { public: static RelativePoint* centered(Figure& aFigure) { RelativePonit* rp = new RelativePoint; rp->setFigurenMessage(aFigure, center); } void setFigurenMessage(Figure& aFigure, int aSymbol()) { figure = aFigure; locationMessage = aSymbol; } }; }}} 이제 일반 Point처럼 사용할 수 있다. {{{~cpp Point RelativePoint::asPoint() { return figure.perform(locationMessage); } Point RelativePoint::x() { return asPoint().x(); } }}} 이런 식으로 하면 CenteredRelativePoint, TopLeftRelativePoint같은 서브클래스를 만들 필요가 없다. 위에서 center라는 메세지를 추가한 것처럼, topLeft메세지를 추가만 하면 되는 것이다. ---- [SBPPSummary]