개요

방문자 패턴은 객체의 구조와 작업을 분리하여 새로운 연산을 추가하거나 기존 연산을 변경할 수 있는 디자인 패턴입니다. 이 패턴을 사용하면 구조 내의 각 요소에 대해 실행할 연산을 변경할 수 있습니다.

구성 요소

  • Visitor: 연산을 수행할 방문자의 인터페이스로, 각 Element 유형에 대해 visit 메소드를 오버로딩하여 정의합니다.
  • ConcreteVisitor: Visitor 인터페이스를 구현하는 클래스로, Element의 각 구현체에 대해 수행될 구체적인 연산을 정의합니다.
  • Element: 방문자가 방문할 요소들의 인터페이스로, accept 메소드를 정의하며, 이 메소드는 Visitor 객체를 매개변수로 받습니다.
  • ConcreteElement: Element 인터페이스를 구현하는 클래스로, 방문자가 실제로 방문할 객체입니다.
  • ObjectStructure: Element 객체들의 집합을 관리하며, 방문자가 구조 내의 각 Element에 접근할 수 있도록 합니다.

작동 방식

방문자 패턴에서는 Visitor 객체가 Element 객체의 accept 메소드를 호출합니다. accept 메소드는 다시 Visitor에게 this를 전달하여 visit 메소드를 호출하게 합니다. 이 과정에서 Visitor는 Element의 구체적인 타입에 따라 오버로딩된 visit 메소드 중 적절한 메소드를 실행하게 됩니다. 이를 통해 Visitor는 다양한 타입의 Element에 대해 서로 다른 연산을 수행할 수 있게 됩니다.

예시: 게임 개발에서의 사용

게임 내 다양한 타입의 필드 객체(FieldObject)에 대해 특정 연산을 수행하고자 할 때 방문자 패턴을 사용할 수 있습니다.

// Visitor 인터페이스
public interface IFieldObjectVisitor
{
    void Visit(Npc npc);
    void Visit(StaticNpc staticNpc);
    void Visit(PC pc);
}

// ConcreteVisitor
public class RenderVisitor : IFieldObjectVisitor
{
    public void Visit(Npc npc)
    {
        // NPC 렌더링 로직
    }

    public void Visit(StaticNpc staticNpc)
    {
        // Static NPC 렌더링 로직
    }

    public void Visit(PC pc)
    {
        // PC 렌더링 로직
    }
}

// Element 인터페이스
public interface IFieldObject
{
    void Accept(IFieldObjectVisitor visitor);
}

// ConcreteElement
public class Npc : IFieldObject
{
    public void Accept(IFieldObjectVisitor visitor)
    {
        visitor.Visit(this);
    }
}

// ObjectStructure는 여러 IFieldObject를 관리하고, RenderVisitor를 통해 각 객체를 방문하며 렌더링합니다.
 
반응형