Vistor Pattern
- '방문자'라는 뜻, 방문자는 어떤 장소에 방문했을 때 장소를 변경시키지 않고 정보를 가져옴
- 특정 객체 구조를 변경시키지 않고 정보를 참고하고 싶을때 사용
구현
- Ivisitor 인터페이스로 구체적인 요소들에 접근할 visit 함수를 매개변수를 달리해 만듬
- 방문을 받고자 하는 요소들을 표시해주기 위해 IElement 인터페이스를 만들고,
방문 가능한(데이터를 얻고싶은) 클래스들에 인터페이스로 추가 - 각 클래스(요소)들은 인터페이스를 상속받아 Ivisitor 타입을 매개변수로 받는 Accept 함수 생성
- 구체적 visitor 클래스에서 데이터를 가져와 어떤 가공을 할 지를 정함( 할인과 같은 기능)
장점
- 구체적 클래스(요소)들의 객체 구조를 변화시키지 않음
IElement를 상속받고, Accept 기능을 추가해야 하긴 하지만, 원래의 '동작' 부분을 변경하진 않음 - 기존 Element 클래스 변경하지 않고, Visitor를 추가해 같은 데이터로 여러 가공을 할 수 있음
- 데이터(객체)와 동작(Visitor)의 분리
단점
- 새로운 Element 추가 시, Visitor 클래스에 추가해줘야함, Element의 확장이 어렵다.
- 복잡성 증가(단순한 프로젝트 시)
사용 이유
각 요소들의 데이터를 오픈한다면 ? : 캡슐화 원칙을 위반하게 됨
각 요소들이 직접 데이터를 전달한다면 ? : 객체의 역할이 추가됨, 단일 책임 원칙에 위배
더해서, 확장성에서도 이점이 있다. 예를 들어, 각 요소의 가격들이 있고 이를 가져와 계산하려 할 때
'할인' 방식과 '기본 방식'으로 계산을 달리해 계산해 클라이언트들에게 전달 가능.
예시 코드
public interface IElement
{
void Accept(IVisitor visitor);
}
public interface IVisitor
{
void Visit(Book book);
void Visit(Fruit fruit);
}
public class Book : IElement
{
public string Title { get; }
public int Price { get; }
public Book(string title, int price)
{
Title = title;
Price = price;
}
public void Accept(IVisitor visitor)
{
visitor.Visit(this); // Visitor를 받아들이고 자신의 데이터를 전달
}
}
public class Fruit : IElement
{
public string Name { get; }
public int Weight { get; }
public Fruit(string name, int weight)
{
Name = name;
Weight = weight;
}
public void Accept(IVisitor visitor)
{
visitor.Visit(this); // Visitor를 받아들이고 자신의 데이터를 전달
}
}
public class PriceCalculatorVisitor : IVisitor
{
private int totalPrice = 0;
public void Visit(Book book)
{
totalPrice += book.Price;
Console.WriteLine($"Book: {book.Title}, Price: {book.Price}");
}
public void Visit(Fruit fruit)
{
totalPrice += fruit.Weight * 2; // 예를 들어 과일 무게로 가격 계산
Console.WriteLine($"Fruit: {fruit.Name}, Calculated Price: {fruit.Weight * 2}");
}
public int GetTotalPrice()
{
return totalPrice;
}
}
public class Program
{
public static void Main()
{
List<IElement> elements = new List<IElement>
{
new Book("C# Programming", 500),
new Fruit("Apple", 3),
new Fruit("Banana", 2)
};
PriceCalculatorVisitor visitor = new PriceCalculatorVisitor();
foreach (var element in elements)
{
element.Accept(visitor); // 각 요소가 Visitor를 받아들임
}
Console.WriteLine($"Total Price: {visitor.GetTotalPrice()}");
}
}
요약
목적 : 원본 데이터와 객체 구조를 훼손하지 않고, 데이터를 받아와 가공하기 위함
구현 : 데이터를 들고 있는 객체들에게 Element 인터페이스로 Accept 함수 구현하게 해 자신의 데이터 전달.
Vistor 인터페이스로 요소들을 모두 방문하게 함(매개변수를 달리하며)
구체적인 vistor클래스마다 받아올 데이터를 가공하는 방식을 달리함
[디자인패턴] 방문자패턴(Visitor Pattern)
Visitor는 사전적인 의미로 어떤 장소에 찾아오는 사람이라는 의미를 갖고 있다. 방문자 패턴에서는 데이터 구조와 처리를 분리한다. 데이터 구조 안을 돌아다니는 주체인 방문자를 나타내는 클
velog.io
https://shan0325.tistory.com/41
[Design Pattern] Visitor(방문자) 패턴이란?
행위 패턴(Behavioral Pattern) 방문자 패턴(Visitor pattern)은 객체 지향 프로그래밍에서 사용되는 디자인 패턴 중 하나로, 객체의 구조와 그 구조에서 수행되는 작업을 분리하여 구현하는 패턴입니다.
shan0325.tistory.com
https://refactoring.guru/ko/design-patterns/visitor
비지터 패턴
/ 디자인 패턴들 / 행동 패턴 비지터 패턴 다음 이름으로도 불립니다: Visitor 의도 비지터(방문자) 패턴은 알고리즘들을 그들이 작동하는 객체들로부터 분리할 수 있도록 하는 행동 디자인 패턴
refactoring.guru
'개념공부' 카테고리의 다른 글
클로저(Closure) (0) | 2025.02.12 |
---|---|
Unity Event System (0) | 2025.01.25 |
디자인 패턴 : 프록시 패턴 (Proxy Pattern) (0) | 2025.01.10 |
디자인 패턴 : 파사드 패턴 (0) | 2025.01.09 |
디자인 패턴 : 컴포지트 패턴 (0) | 2025.01.09 |