방문자 (Visitor) 패턴 행동 패턴
객체 구조에 대한 알고리즘을 외부에서 정의합니다. 방문자 패턴을 통해 객체 구조를 수정하지 않고 새로운 알고리즘을 추가할 수 있습니다.
|
일반적으로 객체에 대한 알고리즘은 객체 안에서 구현되어 객체의 구조와 같이 정의될 수 있다. 하지만, 객체 구조와 큰 관련이 없는 알고리즘을 객체 내에서 구현한다면 객체 지향 프로그래밍에서의 단일 책임 원칙과 개방-폐쇄 원칙을 위배할 수도 있다. 그래서, 이에 대해 동일한 계열의 알고리즘군을 객체 구조 밖으로 빼내어 캡슐화할 수 있도록 방문자 패턴을 사용할 수가 있다.
방문자 (Visitor) 패턴은 객체에 대한 알고리즘을 객체의 구조로부터 분리하여 방문자 객체에 구현하는 패턴이다. 방문자 패턴에서 객체는 방문자 객체에 '방문하여' 객체 구조에 대한 알고리즘을 수행할 수 있게 된다. 객체가 자신에 대한 방문자 객체의 약속된 메소드를 호출하기만 하면, 방문자 객체는 객체 구조에 대한 구체적인 처리를 대행하는 것이다.
방문자 패턴을 사용한다면 객체 구조 밖에서 알고리즘이 구현되어 객체 구조를 수정하지 않고도 실질적으로 새로운 알고리즘을 추가할 수 있고, 방문자 객체를 통해 객체 구조에 크게 관련되지 않는 기능을 한 곳에서 수행할 수 있어 객체 구조에 대한 캡슐화를 유지할 수 있다.
하지만, 객체 구조는 방문자 객체에게 데이터를 공개해야 함으로써 객체 구조의 데이터에 대한 은닉성이 다소 약해질 수 있고, 방문자 객체는 객체 구조를 가로질러 기능을 수행하기 때문에 객체 구조가 변경 될 경우 방문자 객체도 따라서 수정해야 하기에 객체 구조와의 결합이 생길 수 있다. 그래서 방문자 패턴은, 자주 변하지 않는 객체 구조에 대한 사용을 권장한다.
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 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | public class PatternVisitor { public interface IElement { void Accept(IVisitor visitor); } public class ElementA : IElement { public void Accept(IVisitor visitor) { visitor.VisitElementA(this); } public void OperationA() { Console.WriteLine("Operate A"); } } public class ElementB : IElement { public void Accept(IVisitor visitor) { visitor.VisitElementB(this); } public void OperationB() { Console.WriteLine("Operate B"); } } public interface IVisitor { void VisitElementA(ElementA element); void VisitElementB(ElementB element); } public class VisitorA : IVisitor { public void VisitElementA(ElementA element) { element.OperationA(); } public void VisitElementB(ElementB element) { element.OperationB(); } } public static void Main(string[] args) { IVisitor visitor = new VisitorA(); IElement element; element = new ElementA(); element.Accept(visitor); element = new ElementB(); element.Accept(visitor); } } | cs |
1 2 3 | Operate A Operate B Press any key to continue . . . | cs |
위의 예제에서 ElementA 객체와 ElementB 객체는 Accept(IVisitor) 메소드에서 IVisitor 인터페이스의 어떤 메소드를 호출할지 구현되어 있다. 클라이언트가 Accept(IVisitor) 메소드를 호출했을 때 두 객체는 VisitorA 객체의 다른 메소드를 호출하였는데, 이 때 VisitorA 객체에 의해 객체 자신의 OperationA() 메소드와 OperationB() 메소드가 각각 호출되어졌다.
'PROGRAMMING > Design Pattern' 카테고리의 다른 글
[GoF] 중재자 (Mediator) 패턴 (0) | 2019.03.09 |
---|---|
[GoF] 템플릿 메서드 (Template Method) 패턴 (0) | 2019.03.09 |
[GoF] 반복자 (Iterator) 패턴 (0) | 2019.03.09 |
[GoF] 전략 (Strategy) 패턴 (0) | 2019.03.09 |
[GoF] 해석자 (Interpreter) 패턴 (0) | 2019.03.09 |