Skip to main content

Posts

Showing posts with the label pattern

Mediator 중재자

Mediator 객체들 간의 의사소통을 하나 이상의 중재자들이 중재한다. 구성은 Mediator Colleague 예를 들어, 어떤 폼에 버튼과 텍스트 박스가 있을 경우, 버튼이 직접 텍스트 박스를 접근하지 않고, 폼에 작업 요청을 하는 것이다. 버튼에 이벤트가 발생하면, 이를 폼에 전달하여, 폼에서 처리하도록 하는 것이다. 각 객체의 상태에 따라 서로의 상태를 바꾸게 되는데 이 작업을 각 객체들이 대상 객체를 직접 참조하여 상태를 파악하거나 상태를 변경되게 되면, 밀결합이 된다. 그리고 소스 코드가 아주 복잡해지고, 수정 작업이 매우 까다로워진다. 달리 말해, 일부 기능 수정에 따른 타 기능 영향(side effect)이 급격하게 증가하게 된다. 당연히 유지보수 비용은 늘어난다. 이 때, 중재자라는 놈을 이들 사이에 주입한다. 그리고 이들 간의 요청을 중재자에 요청을 하고, 중재자는 모든 객체의 상태를 알아내어서, 조치를 취한다. 구현 방법 1. 관련 colleague들이 하나의 mediator와만 동작한다면, mediator인터페이스는 필요없다. 2. 감시자 패턴을 이용하여, 구현할 수 있다.   colleague에서 상태 변화가 일어날 시, 이를 중재자에 통보하고, 중재자는 처리 방법에 따라 다른 colleague에 이 변경을 전달한다. 3. mediaor 클래스 내에 특화된 통지(notification) 인터페이스를 정의하여, colleague 들이 직접 서로 통신(위임 방식)하게 할 수 있다.

Adapter Pattern

Adapter Pattern wrapper라 불리기도 한다. 개념 기존 클래스를 사용하고 싶은데, 인터페이스가 맞지 않을 때, 이 수법을 사용한다. 예, 110볼트 어댑터를 220볼트 어댑티에 연결할 때, 우리는 변환 어댑터를 끼워사용한다. 적용 사례 인터페이스는 상속을 받고, 구현은 상속하지 않는다. 장단점 요약

Facade Pattern

퍼사드 패턴 Facade Pattern 개념 서브시스템들 사이의 의사소통 및 종속성을 최소화한다. 일단의 서브시스템의 기능성을 단순화된 하나의 인터페이스를 제공한다. 이 인터페이스를 public API, 서브시스템의 각 기능을 private API로 볼 수 있다. 적용 사례 예를 들어, 로그인 처리에 대해서 알아보자. 사용자가 아이디와 패스워드를 입력하고 로그인 버튼을 클릭하면, WAS 측의 로그인 public API가 호출된다. 이 때, 로그인 처리에 필요한 일단의 복수 기능이 호출된다. 이 기능은 계정 유무 판별, 계정 정보, 게임 머니, 오늘의 한마디, 친구 목록, 주간 랭킹 정보등을 들 수 있다. 모든 기능이 처리된 후, 그 결과를 메시지 등의 형태로 클라이언트에 전달된다. 이를 퍼사드 패턴이라 불리고, 로그인 public API가 창구역할(transaction manager)를 하는 인터페이스이고, 그 외를 서브시스템으로 볼 수 있다. 장단점 1. 서브시스템의 구성요소를 보호하고, 은폐할 수 있다. 2. 서브시스템과 사용자 코드 간의 결합도를 약하게 한다. 3. 서브시스템의 재활용도가 높아짐. 요약 객체지향언어에서의 추상클래스의 개념과는 관계없음을 주의하자. 단순히, 하나의 목적을 달성하기 위해, 하나의 함수에서 여러 복잡한 서브시스템를 호출하고, 그 결과를 돌려주는 개념이다.

책임 연쇄 패턴 Chain of responsibility

책임 연쇄 패턴(Chain of Responsibility) 개념 메시지를 보낸 객체와 이를 받아 처리하는 객체 간의 결합도를 없애기 위한 패턴이다. 요청을 처리할 수 있는 객체를 여러 만들고, 요청을 송신하는 객체와 그 요청을 수신하여 처리하는 객체 사이의 결합을 피하는 패턴이다. 그리고 요청을 수신할 수 있는 객체를 연쇄적으로 묶고, 실제 요청을 처리하는 객체를 만날 때까지 고리를 따라 요청을 전달한다. 말이 좀 어려운데.. 이렇게 생각하면 알기 쉽다. 이 해동 패턴은 누군가에게 책임을 떠 넘기는 일이다. 예를 들어, 복리 후생에 관련된 문의가 있어서, 인사과 개똥이 과장에게 문의한다. 개통이 과장이 알면 답변할 것이고, 아니면 멍멍이 과장에게 문의하라고 할 것이다. 그럼 또 마찬가지로 멍멍이 과장에게 문의하면 그는 답변을 하던지 혹은 다른 이에게 문의하라고 할 것이다. 그리고 이 반복은 문의가 완료될 때까지 반복된다. 적용 사례 프로그래밍 관점에서 한번 보자. 어플리케이션이 있고, 그 속에 다이어로그 창이 있다. 그리고 그 창에는 버튼이 있다고 치자. 그리고 모든 컴포넌트에는 도움말 처리 기능이 있다고 하자. 클래스 구성요소와 종속성은 아래와 같다. 다음은 예제 코드이다. 1 Application* application = new Application(message); 2 Dialog* dialog = new Dialog(application, "다이어로그 도움말"); 3 Button* btn = new Button(dialog, "버튼 도움말"); 이 경우, 버튼에서 도움말 요청을 하면, 버튼 도움말이 표시될 것 이다(3번 행에서 설정되어 있으니깐). 하지만, 도움말이 설정되어 있지 않는다면, successor인 다이어로그의 도움말이 처리된다. 장단점 장점 1. 객체 간의 행동 결합도가 현저히 낮아진다. 즉, 객체들 간의 상호 작용 과정을 단순...

Command Pattern

Command Pattern 명령 패턴은 요청 자체를 캡슐화하는 것이다. 서로 다른 요청을 매개변수로 만들고, 원하는 처리를 수행한 후, 되돌릴 수 있는 연산을 수행한다. 요청 자체를 객체로 바꿔서, 명시되지 않은 응용 프로그램 객체의 요청을 처리할 수 있도록 지원하는 패턴이다. 그리고 이 객체는 저장되거나 전달될 수 있다. 이 패턴의 핵심은 연산을 실행하는 데 필요한 인터페이스를 선언해 놓는 Command 추상 클래스이다. 이 클래스의 가장 기본 연산은 Execute()이며, Command 추상 클래스에서 상속 받은 서브클래스들은 수신 객체에 대한 참조자를 인스턴스 변수로 저장하고, 이 수신 객체에 정의된 요청을 호출하도록 Execute()를 구현하여, 수신자 - 작동 쌍의 정의한다. 예를 들어, 홈 오토메이션 리모컨이 있고, 이 리모컨으로 모든 가전 제품을 제어할 수 있다고 했을 때, 리모컨은 receiver가 되고, 각 가전 제품은 concreteCommand가 된다. command class에는 execute가 있고 receiver에서는 각 구현 클래스의 execute함수를 호출한다. 참조문헌 1. GoF 2. http://valley.egloos.com/viewer/?url=http://liepooh.egloos.com/1096056