March
5th,
2025
비지터 패턴(Visitor Pattern)
구조
- 비지터 인터페이스는 객체 구조의 구상요소들을 인수들로 사용할 수 있는 비지터 메서드들의 집합을 선언한다. 이러한 메서드들은 같은 이름을 가질 수 있지만 그들의 매개변수들의 유형은 달라야 한다.
- 구상 비지터는 다양한 구상 요소 클래스들에 맞춤으로 작성된 같은 행동들의 여러 버전을 구현한다
- 요소 인터페이스는 비지터를 수락하는 메서드를 선언한다
- 구상 요소는 수락 메서드를 구현한다. 이 메서드의 목적은 호출을 현재 요소 클래스에 해당하는 적절한 비지터 메서드로 리다이렉트 하는 것이다.
- 클라이언트는 컬렉션 또는 복잡한 객체를 나타낸다.
코드
interface Shape {
fun move(x: Int, y: Int)
fun accept(v: Visitor)
}
class Dot : Shape {
override fun accept(v: Visitor) {
v.visitDot(this)
}
}
class Circle : Shape {
override fun accept(v: Visitor) {
v.visitCircle(this)
}
}
interface Visitor {
fun visitDot(d: Dot)
fun visitCircle(c: Circle)
}
class XMLExportVisitor : Visitor {
override fun visitDot(d: Dot) {
TODO()
}
override fun visitCircle(c: Circle) {
TODO()
}
}
fun main() {
val exportVisitor = XMLExportVisitor()
val circle = Circle()
val dot = Dot()
val list = listOf(circle, dot)
list.forEach {shape -> shape.accept(exportVisitor)}
}
적용
- 비지터 객체는 복잡한객체 구조의 모든 요소에 대해 작업을 수행하야 할때 사용한다
- 비지터 패턴을 사용하여 보조 행동들의 비지니스 로직을 정리한다
- 이 패턴은 행동이 클래스 계층구조의 일부 클래스들에서만 의미가 있고 다른 클래스들에서는 의미가 없을 때 사용
장단점
- 개방폐쇄원칙
- 단일책임원칙
- 다양한 객체와 작업하면서 유용한 정보를 축적할 수 있다
- 클래스가 요소 계층구조에 추가되거나 제거될때 비지터를 업데이트해야한다
- 비지터는 함께 작업해야하는 요소들의 비공개 필드들 및 메서드들에 접근하기 위해 필요한 권한이 부족할 수 있다