Design Pattern for Smalltalk – Memento

t_Dpsc_chapter05_Memento_01

Memento패턴은 기록에 대한 패턴이다. 기록이 필요한 이유는 무엇일까? 기록을 참고해야할 무언가가 있기 때문이다. 기록이 존재함으로서 과거의 이력을 살펴보고, 그 결과로 무언가 다른 행동을 할 수도 있다. 이 경우 다른 행동은 redo/undo 가 될 것이다.

여기서 잠시 객체지향의 3대 요소를 생각해보자. 그렇다! 상속성, 캡슐화, 다형성이다. Memento 패턴이 존재하는 이유를 생각해보자. 객체의 기본은 자신의 내부상태를 외부에 드러내지 않고 동작하는 것에 있다. redo/undo 를 위해 자신의 상태를 필요할 때 마다 외부에서 접근 가능하게 드러내는 것은 캡슐화의 원칙에 위배된다. 이런 필요 덕분에 Memento패턴이 구상되었다. 객체가 필요할 때 자신의 상태를 저장하는 “자신 전용의 별도 창고”에 보관하고, 외부에서의 요청이 있을 때 스스로가 창고에 접근해서 필요한 정보를 용도에 맞게 사용하면 된다.

originator의 Memento class 는 내부적으로 command 패턴 (status의 히스토리 목록을 유지)을 구현하고, 어플리케이션 전첵적으로 command 패턴을 사용하여 이 전체적 패턴에 Originator에 대한 히스토리를 남겨서 관리하면 서로의 간섭이 적은 redo/undo를 구현 할 수 있다. originator의 memento인스턴스 내부에서는 데이터를 collection으로 관리한다고 했을 때, originator의 클라이언트는 memento의 인스턴스를 인식할 수 없기 때문에 캡슐화가 위배되는 경우를 비껴가는데도 유용하다.

Design Pattern for Smalltalk – Mediator

t_Dpsc_chapter05_mediator_01

Mediator패턴은 클래스의 구조에 대한 패턴이라기 보다는 프로그램 내에서 이루어지는 작업의 구조에 대한 패턴이라는게 좀 더 명확한 설명이 될 것이다. 대부분의 패턴이 클래스의 배치와 인터페이스에 대한 문제를 중요하게 다룬다면 Mediator패턴은 객체들 사이의 관계와 작업을 유발시키고, 인스턴스들을 제어하는 방법에 초점이 밪추어져 있다는 것을 유념해야 한다.

다루어야 하는 클래스 (또는 인스턴스)가 여러개가 있고, 이것들이 서로 직접적인 상관관계는 없지만, 프로그램 내에서 필요에 따라 느슨한 결합관계를 가지고 어떠한 이벤트에 여러개의 객체가 반응해야 할 때, 이렇게 여러개의 객체를 매번 일일히(개별로)제어한다는 것은 매우 번거로운 작업이 된다. 이런경우 Business Logic에 따라 일련의 규칙을 가지고 있는 클래스를 만들어서, 이렇게 만들어진 클래스로 하여금 규칙에 따라 필요한 다수의 객체를 제어한다면 편하지 않겠는가? 이 개념을 패턴으로 정리하면 Mediator패턴이 된다.

요즘 대부분의 RDBMS 엔진을 보면 Trigger 개념을 지원하고 있다. Database 내의 특정 table 에 대해 특정 transaction을 조건으로 trigger를 걸어서, 해당 table에 이벤트가 발생되었을 때 부수적인 작업이 진행되도록 설정할 수 있다. 이렇게 작업을 미리 준비 해 놓으면 작업자는 추가적인 고민없이 table에 대한 테이터 질의작업을 진행하면, 필요한 추가작업은 자동으로 미리 준비해놓은 규칙에 따라 순서대로 진행 될 것이다. 일종의 Mediator패턴의 개념으로 동작하는 사례라고 볼 수 있지 않을까?

앞엣 설명한대로 Mediator패턴은, 퍼사드의 인터페이스를 정의하거나 규제하기위한 패턴은 아니다. Mediator클래스의 인터페이스는 작업자가 필요한대로 결정하면 된다. 단 Mediator클래스의 관리를 받아야 하는 상황의 종류가 많아진다면 상황별로 Mediator클래스를 여러개 만들어야 할 필요가 있을텐데(물론 하나의 Mediator에 메서드를 늘여서 해결할 수 있다) 이런 경우라면 라이브러리 내에서 공통으로 사용할만한 메서드 인터페이스를 Mediator추상클래스로 정의하고, Mediator하위클래스에서는 상황별로 구체적인 작업을 구현하는것도 좋은 방법이다.

Design Pattern for Smalltalk – Iterator

t_Dpsc_chapter05_Iterator_01

Iterator패턴에 대해서는 여러가지 설명이 있지만 가볍게 보면 Proxy패턴과 비슷해 보이기도 한다. 뒤쪽에 있는 객체를 감추고 접근권한을 통제 한다는 점에서는 충분히 비슷할 수 있다. 하지만 Iterator패턴의 목적을 명확하게 생각해 볼 필요가 있다. 이 패턴은 자로(데이터)의 제어에 그 목적이 있다. 그것도 자료 객체에 자료를 추가하거나 식제하는 등 자료 자체에 무언가 가공을 하는것이 목적이 아니라 자료의 검색에 대한 인터페이스를 제공하고 그 결과를 공급하는것이 패턴의 목적이다. 좀 더 진지하게 고민해본다면, 자료의 제어와 자료의 제공을 분리해서 자료를 다루는 코드를 개념적으로 나누어 코드관리의 효율성과 확장성을 얻을 수 있게 된다.

하나의 자료구조체에 대해 여러개의 Iterator 클래스를 붙인다면, 원하는 알고리즘으로 자료를 다루는 여러가지 방법을 확보하고, 때에 따라 추가할 수 도 있게 된다. 이 패턴은 데이터의 검색에 대한 알고리즘이 어디에 구현되는지에 따라 분류명이 달라지기도 한다. 알고리즘이 데이터클래스에 위치한다면 Iterator 클래스는 데이터의 탐색만 담당하게 되는데 이런경우를 Cursor라고 한다. 여기서 주의깊게 봐야할 부분은 바로 Cursor라고 불리는 이유이다. Cursor 클래스의 인스턴스를 통해 데이터의 탐색을 하는 경우, 이 인스턴스는 Corrent index 값을 가지게 되는데 이런 특성을 이용하면 여러개의 Cursor 인스턴스가 하나의 원본 데이터에 대한 각기 다른 탐색을 진행할 수 있다.

Iterator패턴은 그 특성상 Iterator클래스가 참조하게 되는 데이터 클래스의 자료구조에 대한 특성에 따라 영향을 받게 되는데, 이런 Iterator패턴의 특수성 때문에 Iterator 클래스의 인스턴스는 원본 데이터의 인스턴스와 생성, 제거를 함께 관리하는 “관리용 클래스”에서 취급되는것이 좋으며, 이렇게 관리 클래스를 별도로 작업하는 경우라면 Proxy 패턴으로 구조를 작업해서 데이터 인스턴스를 참조하는 Iterator 인스턴스에 대한 reference counter를 관리해 주는것이 좋다.