C# Visitor

바로 이전글인 double dispatching 이랑 비교해서 생각해보자

using System;
using System.Collections.Generic;

namespace ConsoleApp3
{
    // 1. Cat, Dog 간 Visitor 구현 코드
    public interface IVisitableElement
    {
        void Accept(IFindSameVisitor visitor);
    }

    public class Animal
    {
    }

    public class Cat : Animal, IVisitableElement
    {
        public void Accept(IFindSameVisitor visitor) => visitor.Visit(this);
    }

    public class Dog : Animal, IVisitableElement
    {
        public void Accept(IFindSameVisitor visitor) => visitor.Visit(this);
    }

    public partial interface IFindSameVisitor
    {
        void Visit(Cat visitor);
        void Visit(Dog visitor);
    }

    public partial class FindSameCat : IFindSameVisitor
    {
        public void Visit(Cat visitor)
        {
            Console.WriteLine("Cat-Cat = Same");
        }

        public void Visit(Dog visitor)
        {
            Console.WriteLine("Cat-Dog = Cute");
        }
    }

    public partial class FindSameDog : IFindSameVisitor
    {
        public void Visit(Cat visitor)
        {
            Console.WriteLine("Dog-Cat = Cute");
        }

        public void Visit(Dog visitor)
        {
            Console.WriteLine("Dog-Dog = Same");
        }
    }

    internal class Program
    {
        static void Main(string[] args)
        {
            // 1차 구현 실행
            var animals1 = new List<IVisitableElement>
            {
                new Cat(), new Dog()
            };

            var catVisitor = new FindSameCat();
            var dogVisitor = new FindSameDog();

            animals1.ForEach(a => a.Accept(catVisitor));
            animals1.ForEach(a => a.Accept(dogVisitor));

            Console.WriteLine();

            // 2차 Mouse 추가 구현 실행
            var animals2 = new List<IVisitableElement>
            {
                new Cat(), new Dog(), new Mouse()
            };

            var mouseVisitor = new FindSameMouse();

            animals2.ForEach(a => a.Accept(catVisitor));
            animals2.ForEach(a => a.Accept(dogVisitor));
            animals2.ForEach(a => a.Accept(mouseVisitor));
        }

    }


    // 2. Mouse가 추가된 경우 추가 구현 코드
    public class Mouse : Animal, IVisitableElement
    {
        public void Accept(IFindSameVisitor visitor) => visitor.Visit(this);
    }

    public partial interface IFindSameVisitor
    {
        void Visit(Mouse visitor);
    }

    public partial class FindSameCat : IFindSameVisitor
    {
        public void Visit(Mouse visitor)
        {
            Console.WriteLine("Cat-Mouse = Mustache");
        }
    }

    public partial class FindSameDog : IFindSameVisitor
    {
        public void Visit(Mouse visitor)
        {
            Console.WriteLine("Dog-Mouse = Four Legs");
        }
    }

    public partial class FindSameMouse : IFindSameVisitor
    {
        public void Visit(Mouse visitor)
        {
            Console.WriteLine("Mouse-Mouse = Same");
        }

        public void Visit(Cat visitor)
        {
            Console.WriteLine("Mouse-Cat = Mustache");
        }

        public void Visit(Dog visitor)
        {
            Console.WriteLine("Mouse-Dog = Four Legs");
        }
    }
}

댓글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다