본문 바로가기
CS

[디자인패턴] 방문자 패턴 (Visitor pattern) 의 개념 및 구조 요약정리

by Warehaus 2022. 10. 30.

 

 

 

2022.08.11 - [CS] - [디자인패턴] GoF Pattern 요약정리와 패턴 별 활용 알아보기

 

[디자인패턴] GoF Pattern 요약정리와 패턴 별 활용 알아보기

요즘 디자인 패턴을 전체적으로 훑어보는 공부를 하고있습니다. 너무나 급변하는 세상이라 쫓아갈 것들이 많지만.. 디자인 패턴은 개발자에게는 거의 근본 그 자체라고 생각하기에 가끔 씩 돌

armin.tistory.com

 

 

오늘은 방문자 패턴, visitor pattern 를 정리해 보려고 합니다.

 

디자인 패턴이라는게

제 부족함 때문인지는 몰라도

볼 때 이해하고

안 쓰면 잊어버리는 묘한 성질을 가지고 있습니다.

 

안 쓴다는 것 자체가

제 게으름을 반증하는 것이 될까요?

 

사담은 이 정도로 하고.. 내용으로 넘어가 봅니다.

 

 

 

목적 

 

- Visitor pattern은 객체 구조에 속한 요소에 수행될 오퍼레이션(알고리즘)을 객체로 정의하여 클래스를 변경하지 않고 새로운 오퍼레이션을 정의할 수 있도록 하는데 그 목적을 둡니다.

- 객체 구조로부터 오퍼레이션 Decoupling

 

 

전공 서적을 볼 때마다 느끼는 점이지만, 내용을 모르고 정의를 보면 잘 이해가 안 갑니다..

한 줄 정의로 의미를 전달할 수 있어야 할 텐데 말이죠.

 

잘 이해해 보기 위해 조금 더 살펴봅니다..

 

 

언제 사용하는가?

 

- 객체 구조가 변경되지는 못하지만, 오퍼레이션 변경은 필요한 경우

- 오퍼레이션에 객체 구조의 세부 클래스에서 동작해야 하는 경우

- 오퍼레이션이 동일한 인터페이스를 구현하는 여러 객체에서 수행되어야 하는 경우

 

 

활용성

 

- 객체 구조가 다른 인터페이스를 가진 클래스들을 포함하고 있어 구체적 클래스에 따라서 오퍼레이션을 수행하고자 할 때

- 구별되고 관련되지 않은 많은 오퍼레이션이 객체에 수행될 필요가 있지만, 오퍼레이션으로 인해 클래스들을 복잡하게 하고 싶지 않을 때.

- 객체 구조를 정의한 클래스는 거의 변하지 않지만, 전체 구조에 걸쳐 새로운 오퍼레이션을 추가하고자 할 때 객체 구조를 변경하려면 모든 visitor 인터페이스의 재정의 필요.

 

 

흠...

솔직히 말하면 저는 이 문장이 이해가 가지 않습니다.

객체 구조가 다른 인터페이스를 가진 클래스..?

 

조금이라도 더 이해해 보기 위해

다이어그램까지 봐야겠습니다..

 

Diagrams

 

출처: Wikipedia

 

Visitor pattern의 Class diagram 은 위 그림과 같습니다.

GoF 디자인 패턴 책에 기재된 내용과 가장 유사한 Diagram입니다.

 

Visitor : 각 ConcreteElement 클래스에 대한 Visit 오퍼레이션을 선언한다.   오퍼레이션의 이름과 인터페이스 형태는 Visit() 요청을 보내는 방문자에게 보내는 클래스를 명시한다. 이로 써, 방문자는 방문 요소의 실제 서브클래스를 결정하게 된다.  그러고 나면 방문자는 Element 가 제공하는 인터페이스를 통해 직접 Element 객체에 접근이 가능하다.

 

ConcreteVisitor : Visitor 클래스에 정의된 오퍼레이션을 구현하는 클래스. 각 오퍼레이션은  객체에 해당하는 클래스에 정의되어 있는 알고리즘을 구현합니다. 

 

 

감이 오시나요?

저는 아주 조금은 감이 오는 것 같습니다.

Visitor 패턴은 아래와 같이 동작하는 것으로 이해됩니다.

 

Visitor를 추상 클래스로 만들고 Concrete Visitor를 만들어서 세부 동작을 정의
Client는 Object structure에 Visitor를 전달
Element 는 Argument로 전달받은 visitor의  accept 메서드를 ConcreteElement에서 실행
ConcreteElement 객체는 Visitor에 구현되어 있는 오퍼레이션을 실행

 

여기서 Visitor는 자신의 알고리즘이 필요한 Concrete Element에서 수행되어야 할 accept  오퍼레이션을 구현해 주어야 할 것입니다.

그래야 객체에서 필요한 수행을 할 수 있을 테니까요

 

 

장점

 

Visitor는 새로운 오퍼레이션 추가를 쉽게 합니다.

- 새로운 visitor 생성을 통해 오퍼레이션 추가를 할 수 있습니다. Element는 그저 Visitor를 실행하면 그만입니다.

 

Visitor는 관련된 오퍼레이션을 모으고, 관련 없는 것들을 분리합니다.

 

단점

 

Element 클래스가 너무 많은 경우에 Visitor의 추가 시 개별 Element 클래스에 대한 구현이 필요합니다. 

- ConcreteElement가 추가되는 경우, 모든 Visitor에 오퍼레이션을 구현해 주어야 합니다.

 

Breaking encapsulation

- 캡슐화를 유지하기가 어렵습니다. ConcreteElement  인터페이스가 Visitor에게 작업을 수행시킬 만큼 꼭 필요한 경우에만 사용하는 것이 좋습니다.