티스토리 뷰
Visitor 디자인 패턴의 핵심은 Visit 메소드와 Accept 메소드를 사용한 데이터 객체와 처리 객체의 분리, 이중 디스패치이지만 다양한 방식으로 구현될 수 있습니다.
class DataA : Data {
void Accept ( Visitor v ) { v.Visit(this); }
}
class VisitorA : Visitor {
void Visit ( DataA d ) { /* process d */ VisitChildren(d); }
}
여기에 반환값을 가지느냐 / 안 가지느냐, 자식 요소 호출을 직접 하느냐 / 자동으로 하느냐에 따라 좀 구현체가 갈립니다.
반환값이 있는 경우 인터프리터 패턴이라고도 불리는 것 같습니다. 하지만 간단한 값을 반환하는 경우가 아니라면 Aggregate(current, next)
함수가 있는 경우가 있습니다. 이 함수가 각 자식 노드에서 반환된 값을 모아 하나로 병합합니다.
자식 요소 호출을 직접 하도록 짠 경우 자식 요소 호출 시점을 마음대로 할 수 있다는 점이 장점입니다. 개별로 직접 방문할수도 있고요. 특히 위의 결과값을 받아오는 경우에서 요긴하게 사용할 수 있습니다. 저는 Visit()
함수 외에도 VisitChildren()
이라는 함수를 BaseVisitor에 구현해서 사용했습니다. BaseVisitor 클래스에는 기본적으로 모든 Visit()
함수가 VisitChildren()
을 호출하게 한 거죠.
아래는 씨샵 기반의 의사코드입니다.
class DataA : Data {
void Accept ( Visitor v ) { v.Visit(this); }
}
class BaseVisitor<T> {
virtual T Aggregate ( BaseVisitor current, BaseVisitor next ) = 0; // 순수 가상 함수 문법 맞나...?
VisitChildren( DataA d ) {
var result = null;
foreach( var child in d ) {
result = Aggregate( result, Visit( child );
}
}
T Visit( DataA d ) { VisitChildren(d); }
}
class VisitorA : BaseVisitor<StringBuffer> {
virtual StringBuffer Aggregate( Visitor current, Visitor next ) { return current.Append(next); }
StringBuffer Visit ( DataA d ) { /* process d */ VisitChildren(d); /* generate result */ return result; }
}
이거 언젠가는 써야지 했던 내용인데 그걸 생각한 지 한참이 지나도록 안 써서 짧게 먼저 써봤습니다. 자세한 내용은 나중에 좀 더 조사해보고 다시 쓰겠습니다.
레퍼런스
- ANTLR 4
- 를 기반으로 썼던 내 코드
- 추후 참조용: Buchlovsky, Peter, and Hayo Thielecke. “A type-theoretic reconstruction of the visitor pattern.” Electronic notes in theoretical computer science 155 (2006): 309-329.
- 살짝 봤는데 이상하고 새롭고 느린 걸 구현했어서 적을만한 가치가 있어보이는 거: Palsberg, Jens, and C. Barry Jay. “The essence of the visitor pattern.” Computer Software and Applications Conference, 1998. COMPSAC’98. Proceedings. The Twenty-Second Annual International. IEEE, 1998.
- 살짝 보다 말았는데 기본적인 내용이 정리되어 있는 거 같았던 거: Nordberg III, Martin E. “Variations on the visitor pattern.” Ann Arbor 1001 (1996): 48108.
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- Sass
- pdf.js
- 마스토돈
- exercism
- ActivityPub
- 왜 생각이 안 났지
- javascript
- gitea
- scss
- Oracle Cloud Infrastructure
- 쿠버네티스
- Godot Engine
- c++
- vuex
- 개발기록
- OStatus
- C#
- 업비트
- 오라클 클라우드 인프라
- K8s
- ArchLinuxARM
- kotlin당했다
- mvu
- C++ FAQ
- 오라클 클라우드
- upbit
- pleroma
- rust-lang
- 토이프로젝트
- 시스어드민
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
글 보관함