1. 방문자 패턴이란? ✨

방문자 패턴은 객체 구조를 변경하지 않고도 새 기능을 추가할 수 있는 디자인 패턴입니다. 특히, 다양한 타입의 객체에 대한 연산을 분리할 때 유용합니다.

예를 들어, 복잡한 객체 구조(트리, 그래프 등)에 서로 다른 연산을 수행해야 한다면, 방문자 패턴을 통해 구조와 연산의 분리를 실현할 수 있습니다.

2. 방문자 패턴의 구성 요소 📦

방문자 패턴은 다음과 같은 구성 요소로 이루어져 있습니다:

  1. Visitor (방문자): 객체 구조의 각 요소를 방문하여 연산을 수행하는 인터페이스입니다.
  2. ConcreteVisitor (구체 방문자): Visitor를 구현하며, 실제 연산을 정의합니다.
  3. Element (요소): Visitor를 수용(accept)하는 인터페이스를 정의합니다.
  4. ConcreteElement (구체 요소): Element를 구현하며, Visitor를 받아들이는 로직을 포함합니다.
  5. ObjectStructure (객체 구조): Element들의 집합으로, Visitor가 이 구조를 순회하며 연산을 수행합니다.

    출처: 위키

3. 방문자 패턴 예제 🌟

아래는 C#으로 작성한 방문자 패턴 예제입니다. 다양한 캐릭터 객체가 있고, 방문자가 이들을 방문하여 연산을 수행하는 상황을 가정합니다.

using System;
using System.Collections.Generic;

// Visitor 인터페이스
public interface IVisitor
{
    void Visit(Warrior warrior);
    void Visit(Mage mage);
}

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

// 구체 요소들
public class Warrior : ICharacter
{
    public string Name { get; set; } = "Warrior";
    public void Accept(IVisitor visitor) => visitor.Visit(this);
}

public class Mage : ICharacter
{
    public string Name { get; set; } = "Mage";
    public void Accept(IVisitor visitor) => visitor.Visit(this);
}

// 구체 방문자
public class DamageCalculator : IVisitor
{
    public void Visit(Warrior warrior)
    {
        Console.WriteLine($"{warrior.Name} takes 50 damage!");
    }

    public void Visit(Mage mage)
    {
        Console.WriteLine($"{mage.Name} takes 70 damage!");
    }
}

// 객체 구조
public class CharacterGroup
{
    private readonly List<ICharacter> _characters = new();

    public void AddCharacter(ICharacter character) => _characters.Add(character);

    public void Accept(IVisitor visitor)
    {
        foreach (var character in _characters)
        {
            character.Accept(visitor);
        }
    }
}

// 사용 예시
public class Program
{
    public static void Main()
    {
        var group = new CharacterGroup();
        group.AddCharacter(new Warrior());
        group.AddCharacter(new Mage());

        var damageCalculator = new DamageCalculator();
        group.Accept(damageCalculator);
    }
}

출력 결과

Warrior takes 50 damage!
Mage takes 70 damage!

4. 방문자 패턴 사용 시 주의할 점 ⚠️

  1. 요소 클래스의 변경에 취약: 새로운 Element를 추가하면 모든 Visitor를 수정해야 합니다.
  2. 객체 구조의 복잡성 증가: 객체 구조가 클수록 관리가 어려워질 수 있습니다.
  3. 사용 적합성 고려: 연산이 자주 변경되거나 추가되는 경우에 적합하지만, 요소의 변화가 잦다면 부적합할 수 있습니다.

5. 결론 ✨

방문자 패턴은 객체 구조와 연산의 분리를 통해 확장성과 유연성을 제공합니다. 특히, 여러 객체에 대해 다양한 연산을 수행할 때 강력한 도구가 됩니다. 다만, 요소의 변경이 많을 경우 관리 비용이 증가할 수 있으므로 상황에 따라 신중히 선택해야 합니다.

6. 관련 링크 🔗

반응형

+ Recent posts