[Design pattern] 방문자 패턴 (Visitor pattern)


Study/Design Pattern  2019. 6. 11. 22:48

안녕하세요. 명월입니다.

 

이 글은 방문자 패턴에 대한 설명입니다.

 

방문자 패턴은 말 그대로 여러 객체를 모아 둔 List에 방문자 클래스를 넣으므로 일괄적으로 처리하게 하는 패턴입니다. 예전에 책에서 본 예제로 가게에 요리사, 홀 서빙, 카운터를 배치시키고 손님이 와서 돈을 내면 그 수익의 분할하는 패턴이라고 쓴 글을 본 적이 있습니다.

정말 말 그래도 딱 적절한 예이지 않을까 싶네요.

 

방문자 패턴은 말은 방문자 패턴인데 실제로는 MVC에서 Model과 Controller의 관계이지 않을까 싶습니다. 데이터 Model이 준비가 완료되면 최종적으로 Controller 선언해서 그 Model를 일괄 처리하는 방식의 패턴입니다.

interface IVisitor
{
  void Visit(Model1 model);
  void Visit(Model2 model);
  void Visit(Model3 model);
}
interface Model
{
  void Accept(IVisitor visitor);
}
class Model1 : Model
{
  public String Data { get; set; }
  public Model1()
  {
    Data = "Model1";
  }
  // 방문자 클래스가 Accept되면 방문자 클래스에 자기 자신을 등록한다.
  public void Accept(IVisitor visitor)
  {
    visitor.Visit(this);
  }
}
class Model2 : Model
{
  public String Data { get; set; }
  public Model2()
  {
    Data = "Model2";
  }
  // 방문자 클래스가 Accept되면 방문자 클래스에 자기 자신을 등록한다.
  public void Accept(IVisitor visitor)
  {
    visitor.Visit(this);
  }
}
class Model3 : Model
{
  public String Data { get; set; }
  public Model3()
  {
    Data = "Model3";
  }
  // 방문자 클래스가 Accept되면 방문자 클래스에 자기 자신을 등록한다.
  public void Accept(IVisitor visitor)
  {
    visitor.Visit(this);
  }
}
class Controller : IVisitor
{
  // Model1 이 있을 때 호출
  public void Visit(Model1 model)
  {
    Console.WriteLine(model.Data);
  }
  // Model2 이 있을 때 호출
  public void Visit(Model2 model)
  {
    Console.WriteLine(model.Data);
  }
  // Model3 이 있을 때 호출
  public void Visit(Model3 model)
  {
    Console.WriteLine(model.Data);
  }
}

class Route : List<Model>
{
  public void Accept(IVisitor visitor)
  {
    foreach(var model in this)
    {
      model.Accept(visitor);
    }
  }
}

class Program
{
  static void Main(string[] args)
  {
    var route = new Route();
    route.Add(new Model1());
    route.Add(new Model2());
    route.Add(new Model3());

    // 결과 Model1 \n Model2 \n Model3
    route.Accept(new Controller());

    Console.WriteLine("Press any key...");
    Console.ReadKey();
  }
}

위 소스를 보면 route클래스에 Model를 선언합니다. 그리고 최종적으로 Controller를 선언해서 Accept함수를 호출해서 결과를 얻는 형태입니다.

 

여기까지 방문자 패턴에 대한 설명이었습니다.

 

궁금한 점이나 잘못된 점이 있으면 댓글 부탁드립니다.