반응형

설명 출처 : https://ko.wikipedia.org/wiki/%ED%8C%A9%ED%86%A0%EB%A6%AC_%EB%A9%94%EC%84%9C%EB%93%9C_%ED%8C%A8%ED%84%B4


code : https://github.com/EomTaeWook/Algorithm/tree/master/Algorithm/DesignPattern/FactoryMethod


팩토리 메서드 패턴(Factory method pattern)은 객체지향 디자인 패턴이다. Factory method는 부모(상위) 클래스에 알려지지 않은 구체 클래스를 생성하는 패턴이며. 자식(하위) 클래스가 어떤 객체를 생성할지를 결정하도록 하는 패턴이기도 하다. 부모(상위) 클래스 코드에 구체 클래스 이름을 감추기 위한 방법으로도 사용한다.


Factory Method라는 패턴 이름이 적절하지 못한데, 이름으로 인해 객체를 생성하는 메소드를 Factory method라 오해하는 개발자가 많이 있다(Allen Holub의 말을 인용.) 이런 생성 메소드가 모두 Factory method 패턴을 사용하는 것은 아니다. Template Method의 생성 패턴 버전으로 볼 수 있는데 Template Method를 알지 못한다면 그 패턴을 먼저 이해하는 것이 Factory Method를 이해하기 수월할 것이다.


Factory Method가 중첩되기 시작하면 굉장히 복잡해 질 수 있다. 또한 상속을 사용하지만 부모(상위) 클래스를 전혀 확장하지 않는다. 따라서 이 패턴은 extends 관계를 잘못 이용한 것으로 볼 수 있다. extends 관계를 남발하게 되면 프로그램의 엔트로피가 높아질 수 있으므로 Factory Method 패턴의 사용을 주의해야 한다.





ICallback.cs


namespace Algorithm.DesignPattern.FactoryMethod

{

    interface ICallback

    {

        void InitCallback();

    }

}


Callback.cs


namespace Algorithm.DesignPattern.FactoryMethod

{

    class CallbackA : ICallback

    {

        public void InitCallback()

        {

            Console.WriteLine("InitCallback A");

        }

    }

    class CallbackB : ICallback

    {

        public void InitCallback()

        {

            Console.WriteLine("InitCallback B");

        }

    }

}


Factory.cs


namespace Algorithm.DesignPattern.FactoryMethod

{

    class Factory

    {

        public enum CallbackType

        {

            CallbackA,

            CallbackB

        }

        public ICallback Create(CallbackType type)

        {

            switch (type)

            {

                case CallbackType.CallbackA:

                    return new CallbackA();

                case CallbackType.CallbackB:

                    return new CallbackB();

                default:

                    throw new System.TypeAccessException();

            }

        }

    }

}

반응형

'디자인패턴' 카테고리의 다른 글

커맨드 패턴(Command Pattern)  (0) 2018.03.17
옵저버 패턴(Observer Pattern)  (0) 2018.03.15
싱글톤 패턴(Singleton Pattern)  (0) 2017.08.11
반응형

설명 출처 : https://ko.wikipedia.org/wiki/%EC%BB%A4%EB%A7%A8%EB%93%9C_%ED%8C%A8%ED%84%B4


code : https://github.com/EomTaeWook/Algorithm/tree/master/Algorithm/DesignPattern/Command


커맨드 패턴(Command pattern)이란 요청을 객체의 형태로 캡슐화하여 사용자가 보낸 요청을 나중에 이용할 수 있도록 매서드 이름, 매개변수 등 요청에 필요한 정보를 저장 또는 로깅, 취소할 수 있게 하는 패턴이다.


커맨드 패턴에는 명령(command), 수신자(receiver), 발동자(invoker), 클라이언트(client)의 네개의 용어가 항상 따른다. 커맨드 객체는 수신자 객체를 가지고 있으며, 수신자의 메서드를 호출하고, 이에 수신자는 자신에게 정의된 메서드를 수행한다. 커맨드 객체는 별도로 발동자 객체에 전달되어 명령을 발동하게 한다. 발동자 객체는 필요에 따라 명령 발동에 대한 기록을 남길 수 있다. 한 발동자 객체에 다수의 커맨드 객체가 전달될 수 있다. 클라이언트 객체는 발동자 객체와 하나 이상의 커맨드 객체를 보유한다. 클라이언트 객체는 어느 시점에서 어떤 명령을 수행할지를 결정한다. 명령을 수행하려면, 클라이언트 객체는 발동자 객체로 커맨드 객체를 전달한다.





IReceiver.cs


namespace Algorithm.DesignPattern.Command
{
    public interface IReceiver
    {
    }

    //ExampleClass
    class Button : DesignPattern.Command.IReceiver
    {
        public void Btn_Click()
        {
            Console.WriteLine("Btn Click");
        }
    }
    class Power : DesignPattern.Command.IReceiver
    {
        public void On()
        {
            Console.WriteLine("PowerOn");
        }
        public void Off()
        {
            Console.WriteLine("PowerOff");
        }
    }
}

ICommand.cs


namespace Algorithm.DesignPattern.Command

{

    public interface ICommand

    {

        void Execute();

        void Undo();

    }


    //ExampleClass

    class ButtonCommand : DesignPattern.Command.ICommand

    {

        Button _receiver;

        public ButtonCommand(DesignPattern.Command.IReceiver receiver)

        {

            _receiver = receiver as Button;

        }

        public void Execute()

        {

            Console.WriteLine("Execute ButtonCommand");

            _receiver.Btn_Click();

        }


        public void Undo()

        {

            Console.WriteLine("Undo PowerCommand");

        }

    }

    class PowerOffCommand : DesignPattern.Command.ICommand

    {

        Power _receiver;

        public PowerOffCommand(DesignPattern.Command.IReceiver receiver)

        {

            _receiver = receiver as Power;

        }


        public void Execute()

        {

            Console.WriteLine("Execute PowerOffCommand");

            _receiver.Off();

        }

        public void Undo()

        {

            Console.WriteLine("Undo PowerOffCommand");

            _receiver.On();

        }

    }

    class PowerOnCommand : DesignPattern.Command.ICommand

    {

        private Power _receiver;

        public PowerOnCommand(Power receiver)

        {

            _receiver = receiver;

        }


        public void Execute()

        {

            Console.WriteLine("Execute PowerOnCommand");

            _receiver.On();

        }

        public void Undo()

        {

            Console.WriteLine("Undo PowerOnCommand");

            _receiver.Off();

        }

    }

}


Program.cs


namespace Algorithm

{

    class Remote

    {

        List<ICommand> _list;

        public Remote()

        {

            _list = new List<ICommand>();

        }

        public Remote Appand(ICommand command)

        {

            _list.Add(command);

            return this;

        }

        public void PowerOn()

        {

            foreach(var command in _list)

            {

                if(command is PowerOnCommand)

                {

                    command.Execute(); break;

                }

            }

        }

        public void PowerOff()

        {

            foreach (var command in _list)

            {

                if (command is PowerOffCommand)

                {

                    command.Execute(); break;

                }

            }

        }

        public void Click()

        {

            foreach (var command in _list)

            {

                if (command is ButtonCommand)

                {

                    command.Execute(); break;

                }

            }

        }

    }

    class Program

    {

        static void Main(string[] args)

        {

            //IReceiver

            Power power = new Power();

            Button button = new Button();


            //ICommand

            ButtonCommand buttonCommand = new ButtonCommand(button);

            PowerOffCommand powerOffCommand = new PowerOffCommand(power);

            PowerOnCommand powerOnCommand = new PowerOnCommand(power);


            //Invoke

            var remote = new Remote();

            remote.Appand(buttonCommand).Appand(powerOffCommand).Appand(powerOnCommand);


            remote.PowerOff();

            remote.PowerOn();

            remote.Click();

        }

    }

}

반응형
반응형

설명 출처 : https://ko.wikipedia.org/wiki/%EC%98%B5%EC%84%9C%EB%B2%84_%ED%8C%A8%ED%84%B4


code : https://github.com/EomTaeWook/Algorithm/tree/master/Algorithm/DesignPattern/Observer


졸업작품 하면서 디자인패턴을 공부했었는데 현재 블로그에 따로 정리한게 자주 쓰는 싱글톤 밖에 없었고 안쓰다보니 까먹은 것도 많고 복습도 할겸 조금씩 정리하려고 한다.


이 패턴의 핵심은 옵저버 또는 리스너(listener)라 불리는 하나 이상의 객체를 관찰 대상이 되는 객체에 등록시킨다. 그리고 각각의 옵저버들은 관찰 대상인 객체가 발생시키는 이벤트를 받아 처리한다.

UML 다이어그램으로는 아래처럼 표현된다. 관찰 대상인 객체는 “이벤트를 발생시키는 주체”라는 의미에서 Subject로 표시되어 있다.



이벤트가 발생하면 각 옵저버는 콜백(callback)을 받는다. notify 함수는 관찰 대상이 발행한 메시지 이외에, 옵서버 자신이 생성한 인자값을 전달할 수도 있다.

각각의 파생 옵서버는 notify 함수를 구현함으로써 이벤트가 발생했을 때 처리할 각자의 동작을 정의해야 한다.

주체에는 일반적으로 등록(register), 제거(unregister) 메서드가 있는데, 전자는 새로운 옵저버를 목록에 등록하고 후자는 목록에서 옵저버를 뺀다. 등록과 제거 메서드 이외에도, 임시로 작동을 멈추거나 재개하는 메서드를 이용해 이벤트가 계속해서 있을 때 홍수같이 발생하는 요청을 제어할 수도 있다.

옵서버 패턴이 많이 쓰인 시스템에서는 순환 실행을 막는 메카니즘이 필요하다. 이벤트 X가 발생하면 옵저버A가 옵저버B를 갱신한다고 가정해보자. 그런데 옵저버B가 이 처리를 위해 옵저버A를 갱신한다면, 이는 다시 A로 하여금 이벤트 X를 발생하게 한다. 이같은 상황을 막기 위해 이벤트 X가 한번 처리된 후에는 A가 이벤트 X를 다시 발생시키지 않는 방법이 요구된다.


C# Event에 옵저버패턴이 녹아져있다고 보면 된다.

http://www.sysnet.pe.kr/Default.aspx?mode=2&sub=0&detail=1&pageno=0&wid=1283&rssMode=1&wtype=0


code>>


IObserver.cs


namespace Algorithm.DesignPattern.Observer

{

    interface IObserver

    {

        void Notify(EventArgs args);

    }

}


Subject.cs


namespace Algorithm.DesignPattern.Observer

{

    class Subject

    {

        private List<IObserver> _observers;

        public Subject()

        {

            _observers = new List<IObserver>();

        }

        public Subject Add(IObserver Item)

        {

            _observers.Add(Item);

            return this;

        }

        public Subject Remove(IObserver Item)

        {

            _observers.Remove(Item);

            return this;

        }

        public void Notify()

        {

            EventArgs args = new EventArgs();

            foreach (var observer in _observers)

            {

                observer.Notify(args);

            }

        }

    }


    //Event 방식의 Observer

    class SubjectEvent

    {

        public delegate void NotifyObserver(EventArgs args);

        public event NotifyObserver NotifyEvent;

        public SubjectEvent()

        {

        }

        public void Notify()

        {

            EventArgs args = new EventArgs();

            NotifyEvent(args);

        }

    }

}



Program.cs


namespace Algorithm

{

    class ConcreateObserverA : DesignPattern.Observer.IObserver

    {

        public void Notify(EventArgs args)

        {

            Console.WriteLine("ConcreateObserverA");

        }

    }

    class ConcreateObserverB : DesignPattern.Observer.IObserver

    {

        public void Notify(EventArgs args)

        {

            Console.WriteLine("ConcreateObserverB");

        }

    }

    class Program

    {

        static void Main(string[] args)

        {

            DesignPattern.Observer.Subject subject = new DesignPattern.Observer.Subject();


            ConcreateObserverA concreateObserverA = new ConcreateObserverA();

            ConcreateObserverB concreateObserverB = new ConcreateObserverB();


            subject.Add(concreateObserverA).Add(concreateObserverB);


            subject.Notify();


            DesignPattern.Observer.SubjectEvent subjectEvent = new DesignPattern.Observer.SubjectEvent();

            subjectEvent.NotifyEvent += concreateObserverA.Notify;

            subjectEvent.NotifyEvent += concreateObserverB.Notify;

            subjectEvent.Notify();

        }

    }

}



반응형
반응형

설명 출처 : https://ko.wikipedia.org/wiki/%EC%8B%B1%EA%B8%80%ED%84%B4_%ED%8C%A8%ED%84%B4


싱글턴 패턴(Singleton pattern)을 따르는 클래스는, 생성자가 여러 차례 호출되더라도 실제로 생성되는 객체는 하나이고 최초 생성 이후에 호출된 생성자는 최초의 생성자가 생성한 객체를 리턴한다. 이와 같은 디자인 유형을 싱글턴 패턴이라고 한다. 주로 공통된 객체를 여러개 생성해서 사용하는 DBCP(DataBase Connection Pool)와 같은 상황에서 많이 사용된다.


public class Singleton

{

private static Singleton instance;

public static Singleton Instance

{

get

{

if (instance == null)

{

instance = new Singleton();

}

return instance;

}

}

}

반응형

'디자인패턴' 카테고리의 다른 글

팩토리 메소드 패턴(Factory Method Pattern)  (0) 2018.03.27
커맨드 패턴(Command Pattern)  (0) 2018.03.17
옵저버 패턴(Observer Pattern)  (0) 2018.03.15

+ Recent posts