본문 바로가기
SW

GoF의 디자인 패턴(Design Patterns: Elements of Reusable Object-Oriented Software) - 2장 사례 연구:문서 편집기 설계(2.8)

by 라꾸스떼(YR) 2020. 4. 14.
반응형

[2.8 철자 검사 및 붙임표 연결]

다양한 기능이 계속적으로 추가될 수 있는 틀을 만들고 싶다. 그러나 이런 기능을 추가할 때마다 Glyph 클래스나 이를 상속하는 서브클래스들을 변경하고 싶지는 않다. 이 퍼즐을 풀려면 두가지 조각을 맞춰야 한다. 1.하나는 분석될 정보에 접근하는 것인데, 이 정보는 문서 구조를 나타내는 여러 글리프에 흩어져 있다. 2.다른 하나는 분석을 직접 하는 것이다.

 

[흩어진 정보에 대한 접근]

우리가 분석해야 하는 텍스트는 글리프 객체의 계층 구조에 흩어져 있다.

Lexi에서 쓰는 접근 방법은 서로 다른 데이터 구조를 포괄할 수 있어야 하며, 서로 다른 순회 방법[postorder, inorder, preorder 등]이 지원되어야 한다.

 

[접근과 순회 방법을 캡슐화하기]

글리프 추상화의 가장 큰 의의는 자식들을 저장하는 자료 구조를 외부에 숨기는 것이었다. 이렇게 해야만 다른 클래스에 영향을 주지 않고 자료 구조를 마음대로 변경할 수 있다. 이를 위해서 어떤 데이터 구조에도 치우치지 않는 인터펭시ㅡㄹ르 정의해야 한다. 즉, ㅇ니터페이스를 보고 글리프가 사용하는 데이터 구조가 무엇인지를 판단할 수 있으면 안 된다.

클래스는 순회 방법이나 접근 방법을 나타내는 나열형(enumerated) 값 중 하나를 선택해서 연산의 매개변수로 전달한다. 그러나 이 방법에도 문제가 있다. 새로운 순회 방법을 추가하려면 나열형 값을 변경하거나 새로운 연산을 추가해야 하기 때문이다.

바로 이럴 때 iterator 객체를 도입할 수 있다. 이 객체의 목적은 다양한 접근과 순회 방법을 일반화해서 정의하는 것이다. 상속을 이용해서 다른 데이터 구조에 동일하게 접ㄱ느할 수 있을 뿐더러 새로운 종류의 순회도 제공할 수 있다. 그리고 glyph 인터페이스를 변경하거나 기존 구현을 어지럽히지 않아도 된다.

 

[iterator(반복자) 클래스와 서브클래스]

구조 접근과 순회에 필요한 일반 핑터페이스를 정의하는 용도로 Iterator 추상 클래스를 사용한다. Iterator의 각 서브클래스는 자신이 순회할 구조에 대한 참조자를 가지며, 서브클래스의 인스턴스는 자신이 생성될 때 자신이 순회할 데이터 구조에 대한 참조자로 초기화된다. Iterator 인터페이스에는 순회를 제어하기 위해 First(), Next()와 IsDone() 연산이 있다. Iterator 클래스 계층의 덕택으로, 새로운 종류의 순회 방법을 추가할 때 기존 Glyph 클래스를 수정하지 않아도 된다. PreorderItrator 클래스를 가지고 한 것처럼 Iterator 클래스의 서브클래스를 만들고 새로운 순회 ㅂ아법을 추가하면 끝이다. Iterator는 순회의 상태에 대한 각자의 사본을 저장하고 있기 때문에, 심지어 하나의 구조에 대해서도 여러 개의 순회를 동시에 진행할 수 있다. C++의 템플릿을 사용하면 쉽게 구현할 수 있다.

 

[반복자 패턴]

반복자 패턴은 객체 구조에 대한 접근 및 순회 방법을 지원하기 위한 기법을 잡아낸 패턴이다. 반복자 패턴은 다양화될 수 있는 개념들을 캡슐화하면 어떻게 유연성과 재사용성 헤택을 취할 수 있는지 보여주는 예이다.

반응형

댓글