2016년 4월 1일 금요일

Design Pattern Digest - 23. Interpreter

이글은 책 "Java언어로 배우는 디자인 패턴 입문"을 읽고 쓴 요약입니다. 
나만 이해하도록 불친절하게 작성되어 있습니다. 
자세한 내용은 책을 보세요. 


Interpreter



  • 프로그램 안에 다른 종류의 언어로 기술된 명령 문서를 처리하는 interpreter를 작성하는 패턴. 좀 특수한 케이스기는 한데, XML이든 JSON이든 parsing하는 코드의 경우에는 이 패턴을 참조할 만하다. 
  • [예제] 명령어를 BNF로 정의하였는데, 예제에서는 BNF 형식에 맞춰서 parsing도 하고 parsing된 결과도 구조적으로 가지고 있는다. BNF에서 꺽쇄로 표현되는 정의들은 모두 NonterminalExpression으로 parsing되어 하위 NonterminalExpression을 다시 가지고 있든지 아니면 TerminalExpression을 가지고 있는다. 


Design Pattern Digest - 22. Command

이글은 책 "Java언어로 배우는 디자인 패턴 입문"을 읽고 쓴 요약입니다. 
나만 이해하도록 불친절하게 작성되어 있습니다. 
자세한 내용은 책을 보세요. 


Command



  • 명령을 객체화 시켜서 관리하는 패턴. Memento와 마찬가지로 프로그램의 undo, redo, history 기능 구현이 목적인데, Memento가 상태를 저장한다면 Command는 명령 이력을 저장 한다.
  • ConcreteCommand는 명령을 수행하는데 필요한 최소한의 정보를 가지고 있고 실제로 명령을 실현하기 위해서는 Receiver가 필요하다. 
  • 명령을 수행하는 지시는 Invoker가 하는데 왜 Invoker가 ConcreteCommand를 직접 보지 않고 Command라는 interface를 보는지는 정확히 알 수 없다. 아마 여러 종류의 command가 있는데 execute() 메소드로 다루기 위함일 것이다. 
  • [예제] (예제가 조금 어려움) Receiver는 Canvas이고 ConcreteCommand는 point를 저장한다. Client이자 Invoker인 main 메소드는 명령을 drawing 명령을 내리거나 clear를 한다. 특이한 점은 command history를 MacroCommand라 하여 또하나의 ConcreteCommand로 만들었다. 


Design Pattern Digest - 21. Proxy

이글은 책 "Java언어로 배우는 디자인 패턴 입문"을 읽고 쓴 요약입니다. 
나만 이해하도록 불친절하게 작성되어 있습니다. 
자세한 내용은 책을 보세요. 


Proxy



  • 진짜 객체를 대신해서 Proxy가 대신 처리해주는 패턴.
  • Network이나 Printer같이 진짜 객체를 생성하고 진짜가 처리하는 것을 대신해서 같은 interface의 Proxy가 가벼운 처리를 대신해준다. HTTP의 Proxy가 caching하는 것도 이러한 사례라고 볼 수 있다. 
  • 처리하지 못하는 어쩔 수 없는 경우에는 진짜 객체를 생성시킨다. 
  • Proxy와 RealSubject는 Subject interface를 통해 메소드가 동일하기 때문에 Client는 Subject interface를 다루지만 실제로 앞단에서 처리하는 것은 Proxy이다. 즉, Client는 그것이 Proxy에 의해 처리되든 RealSubject에 의해 처리되든 상관할 바 아니다. 


Design Pattern Digest - 20. Flyweight

이글은 책 "Java언어로 배우는 디자인 패턴 입문"을 읽고 쓴 요약입니다. 
나만 이해하도록 불친절하게 작성되어 있습니다. 
자세한 내용은 책을 보세요. 


Flyweight



  • 객체를 재사용하는 (공유하는) 패턴.
  • Flyweight 클래스가 특정한 state/value에 대해서 하나의 instance가 재사용되어도 좋다면 FlyweightFactory 클래스가 이것들의 instance를 map같은데 관리하고 있다가 필요하다고 하는 곳에 제공해준다. 
  • FlyweightFactory는 싱글톤으로 구현하고 여기서 Flyweight들의 map을 가지고 있는데 key를 통해서 얻어올 수 있다. 만일 특정 key에대해 이미 생성된 Flyweight 인스턴스가 없다면 그때 만들어서 주면 된다. 
  • 책에는 ConcreteFlyweigth와 UnsharedConcreteFlyweight에 대한 언급은 없는데 중요한 부분은 아닌듯.



Design Pattern Digest - 19. State

이글은 책 "Java언어로 배우는 디자인 패턴 입문"을 읽고 쓴 요약입니다. 
나만 이해하도록 불친절하게 작성되어 있습니다. 
자세한 내용은 책을 보세요. 


State



  • 상태 변화에 따라서 정의된 모든 action들 - 그림에선 handle() - 에 대한 처리를 각 State가 알아서 진행하는 패턴.
  • ConcreteState는 Singleton으로 생성되어 상태에 따라 Context의 state 변수에 assign된다.
  • State 변경 판단은 각 ConcreteState에서 한다. (ConcreteState간의 독립성이 조금 훼손된다. 어쩔 수 없다. 중앙에서 상태 관리하면 Mediator 패턴처럼 되는데 이 역시 Context가 모든 ConcreteState를 알아야한다는 단점이 있다.)
  • [예제]: Context에 SafeFrame이라는 금고앱. 시간 설정을 하고 주간, 야간 상태에 따라 금고 사용, 비상 벨 사용, 통화 버튼의 동작이 달라진다. ConcreteState는 DayState와 NightState. 



Design Pattern Digest - 18. Memento

이글은 책 "Java언어로 배우는 디자인 패턴 입문"을 읽고 쓴 요약입니다. 
나만 이해하도록 불친절하게 작성되어 있습니다. 
자세한 내용은 책을 보세요. 


Memento



  • 프로그램의 undo, redo, history 기능을 위한 상태 저장 용도로 사용
  • Polymorphysm을 사용하지 않는 패턴이다. 
  • Memento 클래스는 Originator의 상태를 나타내는데, 이것의 생성은 같은 package에 속한 Originator가 한다. (Memento의 생성자는 package private이다) 또 Originator는 외부로부터 Memento를 전달 받으면 그걸로 상태를 복원한다.
  • Caretaker는 Originator에게 '상태를 저장해라'라고 명령을 내리고 Memento를 관리한다. 필요하면 저장된 Memento를 Originator에게 전달하면서 '상태를 복원해라'라고 명령을 내린다.
  • Originator는 Memento의 생성자와 같은 narrow interface를 사용할 수 있고, Caretaker는 주로 getter와 같은 Mementor의 wide interface를 사용한다. 


Design Pattern Digest - 17. Observer

이글은 책 "Java언어로 배우는 디자인 패턴 입문"을 읽고 쓴 요약입니다. 
나만 이해하도록 불친절하게 작성되어 있습니다. 
자세한 내용은 책을 보세요. 


Observer




  • Android에 많이 쓰는 Observer들과 유사하다. (e.g. GUI의 action listener들)
  • Observer interface를 구현한 ConcreteObserver 클래스를 Subject에 등록하면 Subject의 내부 상태 변화나 이벤트 발생시 등록된 Observer들을 모두 호출하여 준다. (Publish-Subscribe 모델이기도 하다)
  • Subject의 상태 변화 메소드를 Observer가 호출하는 것과 같이 Subject의 상태를 변화시킬 수 있는데 이 경우 Observer 호출 도중에 다시 Observer를 호출하는 무한 호출 오류가 발생할 수 있다. 따라서 한 turn의 호출이 완료될 수 있도록 상태변수를 두는 것이 좋다.
  • Subject도 interface로서 Observer들이 다양한 형태의 ConcreteSubject들의 변화를 통보 받을 수 있도록 한다.