목차
방문자 패턴
유니티에서 방문자 패턴(Visitor Pattern)은 객체 지향 디자인 패턴 중 하나로, 객체 구조 내에서 새로운 기능을 추가할 때 사용되는 패턴입니다. 방문자 패턴의 주요 목적은 기존의 객체 구조를 변경하지 않고 새로운 연산을 추가하는 것입니다.
방문자 패턴 UML
방문자 패턴의 UML은 아래와 같습니다.
•
Visitor : 인터페이스로, 새로운 연산을 정의합니다. ConcreteVisitor들이 이 인터페이스를 구현해야 합니다.
•
ConcreteVisitor : Visitor 인터페이스를 구현하는 클래스로, 각각의 ConcreteElement에 대한 visit 메서드를 정의합니다. 이 메서드들은 객체 구조의 각 요소에 대해 수행할 새로운 연산을 구현합니다.
•
Element : 인터페이스로서, 객체 구조의 각 요소를 나타냅니다. accept 메서드를 포함하여 Visitor 객체가 객체 구조를 방문할 수 있게 합니다.
•
ConcreteElement(요소) : Element 인터페이스를 구현하는 실제 객체 구조의 구성 요소 클래스입니다. 각 클래스는 accept 메서드를 통해 ConcreteVisitor 객체를 받아들입니다.
방문자 패턴의 장단점
장점
•
동작 추가 : 직접 수정하지 않고도 다른 클래스의 동작을 추가할 수 있습니다.
•
단일 책임 : 방문자 패턴은 데이터를 보유하는 객체를 가질 수 있고 또 다른 객체는 특정 행동을 도입하는 책임을 진다는 점에서 단일 책임 원칙을 준수합니다.
단점
•
복잡성 : 기본 구조에서 명령 패턴과 같이 동작을 구분하는 것이다 보니 동작이 많아진다면, 복잡해질 수 있습니다. 다만, 동작 자체가 복잡한 동작이라면, 이 부분이 오히려 장점이 될 수 있습니다.
방문자 패턴 구현하기
•
Visitor 인터페이스와 Element 인터페이스 정의
using UnityEngine;
public interface IVisitor
{
void Visit(TransformElement element);
}
public interface IElement
{
void Accept(IVisitor visitor);
}
C#
복사
•
Element 인터페이스를 구현한 ConcreteElement 클래스를 만들겠습니다.
public class TransformElement : MonoBehaviour, IElement
{
public void Accept(IVisitor visitor)
{
visitor.Visit(this);
}
}
C#
복사
•
Visitor 인터페이스를 구현한 ConcreteVisitor 클래스를 작성합니다.
public class MoveUpVisitor : IVisitor
{
private float _distance;
public MoveUpVisitor(float distance)
{
_distance = distance;
}
public void Visit(TransformElement element)
{
element.transform.position += Vector3.up * _distance;
}
}
C#
복사
•
방문자 패턴을 사용하여 게임 오브젝트를 이동시키는 ObjectStructure 클래스를 구현하겠습니다.
using System.Collections.Generic;
using UnityEngine;
public class ObjectStructure : MonoBehaviour // ScriptableObject로 구현하는 것도 바람직
{
[SerializeField] private List<TransformElement> _elements;
private void Start()
{
MoveUpVisitor moveUpVisitor = new MoveUpVisitor(2f);
foreach (TransformElement element in _elements)
{
element.Accept(moveUpVisitor);
}
}
}
C#
복사
방문자 패턴에 대하여..
개인적으로 별로 좋아하지 않는 패턴 중 하나입니다.
이유는 방문자 패턴의 특징인 해당 객체의 동작을 처음부터 갖고 있지 않고 IVisitor 인터페이스를 상속받은 객체의 동작에서 동작을 진행한다는 점 때문입니다.
이는 명령 패턴처럼 명령을 객체화하는 장점을 갖고 있긴 하지만, 명령 패턴은 동작을 객체화하는 것에 중점을 두고 패턴을 짜기 때문에 구조 자체가 명령 패턴을 사용하지 않았을 때와 차이가 있습니다.
방문자 패턴의 주요 목적은 객체 구조의 클래스를 수정하지 않고 새로운 연산을 추가하는 것입니다.
즉, 기본 구조를 토대로 작성하기에 방문자 패턴에 사용되는 동작들을 기본 구조에 넣어도 무방합니다. 때문에, 방문자 패턴을 과도하게 사용하여 구조가 이상해지지 않도록 주의해야 합니다.
개인적으로 방문자 패턴을 사용하는 좋은 방법은 추상 클래스와 기본 인터페이스를 사용하여 일반적인 구조를 먼저 짜고 방문자 패턴으로 분리하면 좋을 것들을 선택해서 분리하는 것입니다.
위와 같이 관리한다면, 기본 구조에서 크게 벗어나지 않고 예외적인 사항이 발생했을 때 방문자 패턴을 사용하여 유지보수를 깔끔하게 할 수 있을 것입니다.