아헿헿헿 2022. 6. 1. 20:32

1. 용도

객체 구조를 이루는 원소에 대한 수행할 연산을 표현합니다. 연산을 적용할 원소의 클래스를 변경하지 않고도 새로운 연산을 정의할 수 있게 합니다.


2.  활용성

  • 다른 인터페이스를 가진 클래스가 객체 구조에 포함되어 있으며, 구체 클래스에 따라 달라진 연산을 이들 클래스의 객체에 대해 수행하고자 할 때
  • 가각 특징이 있고, 관련되지 않은 많은 연산들이 한 객체 구조에 속해있는 객체들에 대해 수행될 필요가 있으며, 연산으로 클래스들을 더럽히고 싶지 않을 때
  • 객체 구조를 정의한 클래스는 거의 변하지 않지만, 전체 구조에 걸쳐 새로운 연산을 추가하고 싶을 떄

3. Class Diagram과 구조

[Visitor] - 객체 구조 내에 있는 각 ConcreteElement 클래스를 위한 Visit 연산을 선언하여, 방문자는 방문된 원소의 구체 클래스를 결정할 수 있습니다.

[ConcreteVisitor] - Visitor 클래스에 선언된 연산을 구현합니다. 알고리즘이 운영될 수 있는 상황 정보를 제공하며 자체 상태를 저장합니다.

[Element] - 방문자를 인자로 받아들이는 연산을 정의합니다.

[ConcreteElement] - 인자로 방문자 객체를 받아들이느 연산을 구현합니다.

[ObjectStructure] -객체 구조 내의 원소들을 나열할 수 있습니다. 방문자가 이 원소에 접근하게 하는 상위 수준 인터페이스를 제공합니다.

 

사용자는 ConcreteVisitor 클래스의 객체를 생성하고 객체 구조를 따라서 각 원소를 방문하며 순회해야합니다. 이 때 구성 원소는 해당 클래스의 Visitor 연산을 호출하여, 방문자 자신의 상태에 접근할 수 있도록 합니다.


4. 장단점

장점

  • Visitor 클래스에 새로운 연산 쉽게 추가- 복잡한 객체를 구성하는 요소에 속한 연산을 새로운 방문자를 추가하여 쉽게 추가할 수 있습니다.
  • 방문자를 통해 관련된 연산들을 한 군데 모으고 관련되지 않은 연산을 떼어낼 수 있음
  • 상태를 누적할 수 있습니다. - 방문자가 객체 구조 내 각 원소들을 방문하면서 상태를 누적가능합니다. 이가 없다면, 전역 변수로 존재해야 하거나 다른 연산이 할당되어야 합니다.
  • 클래스 계층 구조에 걸쳐서 방문 - 방문자는 서로 다른 타입의 원소를 갖는 객체 구조에 대해서도 순회가 가능합니다.

단점

  • 새로운 ConcreteElement 클래스 추가가 어려움 - ConcreteElement 클래스가 생길 때 마다, Visitor 클래스에 대한 새로운 추상 연산 및 모든 클래스에 그 연산에 대응하는 구현을 제공해야 합니다.
  • 데이터 은닉을 깰 수 있습니다. - 개발자는 ConcreteElement원소의 내부 상태에 접근하는 데 필요한 연산들을 모두 공개 인터페이스로 만들 수 밖에 없기에  캡슐화 전략을 위배합니다.

5. 구현 방법

  1. 단일 디스패치 - 사용자가 클래스 변경하지 않고 연산을 클래스에 추가하도록 만드는 패턴입니다. 이를 위해 요청의 이름과 수신자의 타입을 통해 알맞는 연산을 수행합니다.
  2. 객체 구조 순회 책임 문제 - 각 객체 구조 요소를 방문할 때 어떻게 가는지가 큰 쟁점이 되는데, 객체 구조, 방문자, 혹은 별도의 반복자 객체를 사용하여 이를 구현 가능합니다.