부모 클래스 또는 인터페이스를 이용하여 하위 요소를 생성 및 사용할 때 이용되는 패턴입니다.

 

using System;

namespace ConsoleApp
{
    class Program
    {
        public static void Main(string[] args)
        {
            int size = 3;
            int player = 0;
            Unit[] unit = new Unit[size];

            while (player < size)
            {
                Console.WriteLine("{0}p 종족을 입력하세요: (Zerg, Protoss, Terran)", player + 1);
                string race = Console.ReadLine();

                switch (race)
                {
                    case "Zerg":
                        unit[player] = new Zerg();
                        player++;
                        break;
                    case "Protoss":
                        unit[player] = new Protoss();
                        player++;
                        break;
                    case "Terran":
                        unit[player] = new Terran();
                        player++;
                        break;
                    default:
                        break;
                }
            }

            Console.WriteLine();
            foreach (Unit u in unit)
            {
                u.ShowType();
            }
        }
    }

    abstract class Unit
    {
        public abstract void ShowType();
    }

    class Zerg : Unit
    {
        public override void ShowType()
        {
            Console.WriteLine("Zerg");
        }
    }

    class Protoss : Unit
    {
        public override void ShowType()
        {
            Console.WriteLine("Protoss");
        }
    }

    class Terran : Unit
    {
        public override void ShowType()
        {
            Console.WriteLine("Terran");
        }
    }
}

실행 결과

 

단 하나의 인스턴스를 통해 해당 클래스에 접근 및 사용할 수 있습니다.

다른 객체들간의 통신 등에도 유용하게 쓸 수 있는 방법!

 

using System;

namespace ConsoleApp
{
    class Program
    {
        public static void Main(string[] args)
        {
            GameManager.GetInstance().PrintHello();
        }
    }

    class GameManager
    {
        private static GameManager instance = new GameManager();
        public static GameManager GetInstance ()
        {
            return instance;
        }

        private GameManager()
        {
            //private로 외부에서 생성을 못하게 막아줍니다.
        }

        public void PrintHello()
        {
            Console.WriteLine("Hello");
        }
    }
}

등록 된 관측자들에게 메시지를 전달해주는 패턴. (EventListener 등과 같이 알게 모르게 많이 쓰이고 있습니다.)

인터페이스보다 델리게이트 사용이 더 간단한 듯합니다.

 

using System;

namespace ConsoleApp
{
    class Program
    {
        public static void Main (string[] args)
        {
            Teacher t = new Teacher();
            Observer_Student marine = new Observer_Student("마린");
            Observer_Student zealot = new Observer_Student("질럿");
            Observer_Student zergling = new Observer_Student("저글링");

            t.AddStudent(marine);
            t.AddStudent(zealot);
            t.AddStudent(zergling);

            Console.WriteLine();
            t.ClassStart("달리기");

            Console.WriteLine();
            t.RemoveStudent(marine);

            Console.WriteLine();
            t.ClassStart("근접 공격");
            
            Console.ReadKey();
        }
    }

    class Teacher
    {
        private delegate void Teach(string subject);
        private Teach teach;
        
        public void AddStudent (Observer_Student student)
        {
            Console.WriteLine("{0}이 등록됩니다.", student.name);
            teach += student.Learn;
        }

        public void RemoveStudent (Observer_Student student)
        {
            Console.WriteLine("{0}이 등록 해제됩니다.", student.name);
            teach -= student.Learn;
        }

        public void ClassStart (string subject)
        {
            teach(subject);
        }
    }

    class Observer_Student
    {
        public string name;
     
        public Observer_Student(string name)
        {
            this.name = name;
        }

        public void Learn (string subject)
        {
            Console.WriteLine("{0}은 {1} 수업을 받고 있습니다.", name, subject);
        }
    }
}

 

실행 결과

 

특정한 동작에 대해 클래스 내부에 대한 수정이 아니라 클래스 외부에서 수정하도록 설계 해둔 패턴!

인터페이스 또는 델리게이트를 사용하여 구현할 수 있겠습니다.

 

using System;

namespace ConsoleApp
{
    class Program
    {
        public static void Main (string[] args)
        {
            Unit marine = new Unit();
            Unit zerling = new Unit();
            Unit medic = new Unit();

            marine.SetAttack(new Marine());
            zerling.SetAttack(new Zergling());
            medic.SetHeal(new Medic());

            marine.Attack();
            marine.Heal();

            zerling.Attack();
            zerling.Heal();
            
            medic.Attack();
            medic.Heal();
        }
    }

    class Unit
    {
        private IAttack attack = null;
        private IHeal heal = null;

        public void Attack ()
        {
            if (attack != null)
            {
                attack.Attack();
            }
        }

        public void Heal ()
        {
            if (heal != null)
            {
                heal.Heal();
            }
        }

        public void SetAttack (IAttack attack)
        {
            this.attack = attack;
        }

        public void SetHeal (IHeal heal)
        {
            this.heal = heal;
        }
    }

    interface IAttack
    {
        void Attack();
    }

    interface IHeal
    {
        void Heal();
    }

    class Marine : IAttack
    {
        public void Attack ()
        {
            Console.WriteLine("가우스 라이플 공격");
        }
    }

    class Zergling : IAttack
    {
        public void Attack()
        {
            Console.WriteLine("발톱 공격");
        }
    }

    class Medic : IHeal
    {
        public void Heal ()
        {
            Console.WriteLine("치료");
        }
    }
}

 

실행 결과

 

+ Recent posts