글

라벨이 design pattern인 게시물 표시

디자인 패턴 #6 - 커맨드 패턴 (command pattern)

이미지
1. 커맨드 패턴 (command pattern) 각종 기능을 캡슐화하여 여러 기능을 실행/관리할 수 있다. 커맨드 패턴을 이용하면 요구 사항을 객체로 캡슐화 할 수 있으며, 매개변수를 써서 여러가지 다른 요구 사항을 집어 넣을 수도 있다. 또한 요청 내역을 큐에 저장하거나 로그로 기록할 수도 있으며, 작업 취소 기능도 지원할 수 있다. 커맨드 패턴은 (1)명령, (2)수신자, (3)발동자, (4)클라이언트로 이루어진다. - 명령(command) : 수행 동작을 담고 있는 클래스 - 수신자(receiver) : 명령 수행하는 클래스 (ex. TV, 오디오 등 각종 기기) - 발동자(invoker) : 명령 수행을 요청하는 클래스 (ex. 리모컨) - 클라이언트(client) : 어떤 명령을 수행할지 결정하는 클래스 (1) 명령 LightOnCommand 클래스는 Command 인터페이스를 구현하여, Light 객체의 On/Off를 실행할 수 있다. (2) 수신자 Light 클래스는 장소(mPlace)의 점/소등을 할 수 있다. Command 클래스의 execute() 메소드에서 호출한다. (3) 발동자 RemoteControl 클래스는 입력된 Command를 실행한다. 총 7개의 slot이 존재하고, 미리 Command를 입력한 뒤, slot 번호를 통해 명령을 실행할 수 있다. onButtonWasPushed()와 함께 slot 번호를 입력하면 slot에 해당하는 기기의 정의된 동작을 수행하게 된다. (4) 클라이언트 각 Command 객체와 RemoteControl 객체 생성한다. 명령의 실행과 시점을 결정한다. 하기에서는 main 클래스가 해당 역할을 담당한다. LivingRoom과 Kitchen의 점등과 소등 명령을 정의하였으며, onButtonWasPushed(), offButtonWasPushed()를 통해 실행할 수 있다. 2. 결과 수행 결과는 하기와 같다. 각 slot에 해당하는 사...

디자인 패턴 #3 - 데코레이터 패턴 (decorator pattern)

이미지
1. 데코레이터 패턴 (decorator pattern) 데코레이터 패턴에서는 객체에 추가적인 요건을 동적으로 첨가한다. 데코레이터는 서브클래스를 만드는 것을 통해서 기능을 유연하게 확장할 수 있는 방법을 제공한다. 쉽게 말해 샌드위치와 같이 본래의 재료에 무언가를 추가할 때 사용된다. 클래스 다이어그램을 살펴보면 Component는 기본적인 재료를 의미한다. 샌드위치로 예를 들자면 Component는 "빵"이라고 할 수 있다. 기본 재료인 "빵"에 Decorator 를 상속받은 ConcreteDecoratorA, ConcreteDecoratorB를 사용하여 각종 햄, 야채, 소스를 추가하면 된다. Decorator 객체는 Component의 reference를 가지고 있고, 이 곳에 꾸며야 할 객체(ConcreteComponent)를 전달받아 여러 가지 동작/정보를 추가하게 된다. Beverage 클래스는 Component에 해당하는 객체로 기본적인 음료를 나타내는 추상 클래스이다. CondimentDecorator 클래스는 Decorator의 역할을 하는 클래스로 첨가물을 나타내는 추상클래스이다. 전달받은 Beverage 클래스를 저장하여, 꾸며 주게(첨가물 추가) 된다. DarkRoast 객체는 Beverage를 상속받은 클래스로 ConcreteComponent의 역할을 한다. 명칭과 가격을 정의했다.  마지막으로 Moca 클래스는 ConcreteDecorateA의 역할을 하며, 넘겨받는 DarkRoast 클래스에 Moca를 추가하고, 명칭과 가격을 꾸며주게 된다. 사용하는 코드는 다음과 같다. 자바 I/O 패키지에 데코레이터 패턴이 다수 적용되어 있다. FileInputStream → BufferedInputStream → LineNumberInputStream으로 이어지는 확장 구조를 가지고 있다. FileInputSream은 파일을 읽어들이는 기본 동작을 정의하며...

디자인 패턴 #2 - 옵저버 패턴 (observer pattern)

이미지
1. 옵저버 패턴 (observer pattern) 옵저버 패턴(observer pattern)은 한 객체의 상태가 바뀌면 그 객체에 의존하는 다른 객체들한테 연락이 가고 자동으로 내용이 갱신되는 방식으로 일대다(one-to-many) 의존성을 가지는 구조를 의미한다. 쉽게 말해 여행 준비를 할 때 '준비가 완료되었는지 매 순간 확인하지 않고, 준비가 완료되면 연락받는 것'과 같다. 옵저버 패턴은 느슨한 결합(loose coupling)으로 두 객체가 연결되는데, 이는 상호작용을 하긴 하지만 서로에 대해 잘 모른다는 것을 의미한다. 옵저버(연락을 받는 객체)가 연락을 받고 싶다면 주체(연락을 하는 객체)에서 정의한 interface를 구현한 뒤 주체에게 등록만 하면 된다. 주체는 옵저버가 무엇을하는지 어떤 클래스를 상속받고 있는지 등에 대해 전혀 알지 않아도 되며, 주체 또는 옵저버가 바뀌더라도 서로에게 영향을 미치지 않는다. 각각의 코드를 살펴보면 ConcretePublischer 객체는 연락을하는 주체로 Observer가 등록되면 ArrayList로 Observer관리하고 이벤트 발생 시 loop를 돌며 등록된 observer에 연락을 준다. registerObserver()를 통해 옵저버를 등록할 수 있으며, unregisterObserver()를 통해 등록된 옵저버를 제거할 수 있다. 연락을 받는 옵저버는 옵저버 interface를 구현한 뒤 Publisher에게 연락을 받기 위해 등록하면 연락받을 준비가 완료되며, 이 후 Publisher에서 Callback이 오면 해당 동작을 처리하면된다. 옵저버 패턴을 사용하면 어떤 정보가 필요한 경우 매 번 확인을 하지 않고, 이벤트가 발생하는 순간에 주체로부터 연락을 받을 수 있다. 옵저버 패턴의 일반적인 사례는 사용자 입력에 대한 이벤트(OnClickListener) 처리가 있으며, MVC(Model-View-Controller) 패턴과 자주 ...

디자인 패턴 #1 - 스트래티지 패턴 (strategy pattern)

이미지
1. 스트래티지 패턴 (strategy pattern) 스트래티지 패턴(strategy pattern)에서는 알고리즘군을 정의하고 각각을 캡슐화하여 교환해서 사용할 수 있도록 만든다. 스트래티지를 활용하면 알고리즘을 사용하는 클라이언트와는 독립적으로 알고리즘을 변경할 수 있다. 쉽게 이야기하자면 지정된 알고리즘의 세부 구현을 변경할 필요없이 쉽게 교환할 수 있게 해주는 디자인 패턴이다. 클래스 다이어그램을 살펴보면 오리의 행동을 정의한 2가지 interface가 존재하고, Duck 클래스를 상속받은 오리(MallardDuck, RedheadDuck, RubberDuck)은 각자에게 맞는 행동 객체를 할당하여 사용할 수 있다. 만일 행위가 변경된다면 원하는 행동 객체를 할당하여 쉽게 교체하여 사용할 수 있다. 하기의 RubberDuck을 구현한 코드를 살펴보면 RubberDuck에 맞게 FlyBehavior와 QuackBehavior에 객체를 할당하여 사용하면 되며, 행위에 변경이 발생하더라도 해당 행위에 맞는 객체로 교체해주면 쉽게 동작을 변경할 수 있다. 위의 방식처럼 클래스를 합치는 것을 구성(composition) 관계라 한다. 구성(composition)이란 클래스를 상속하는 대신 기존 클래스(super class)의 인스턴스를 참조하는 private 필드를 서브 클래스로 만들고자 했던 클래스에 만드는 것이다. 즉 RubberDuck 클래스는 Duck 클래스를 상속하는 대신에 Duck 클래스에 추가된 FlyBehavior와 QuackBehavior를 RubberDuck 클래스에서 행동에 맞는 객체를 할당하여 사용하였다. 이와같이 구조를 잡을 때에는 각 클래스의 관계가 'is-a'인지, 'has-a'인지를 이해하고, 관계에 맞는 구조를 잡아주는 것이 좋다. 만일 두 클래스 간의 관계에 대해 자신있게 'is-a'가 맞다고 이야기할 수 없다면 상속(inheritance)은 피해야 하며, ...

디자인 패턴 (design pattern)

이미지
1. 디자인 패턴 (design pattern) 디자인 패턴은 개발 과정에서 겪게되는 공통된 문제들에 대해 전문가들의 경험을 모아 표준적인 해법을 구조화한 것으로, 디자인 패턴을 숙지하면 개발자간의 원활한 커뮤니케이션이 가능해진다. 디자인 패턴은 GoF(Gang of Four)에 의한 고안된 것으로 보는 것이 일반적이다. GoF는 에릭 감마(Erich Gamma), 리처드 헬름(Richard Helm), 랄프 존슨(Ralph Johnson), 존 블리스데스(John Vlissides)에 의해 고안된 것으로 알려져있다. 2. SOLID 원칙 좋은 객체지향 설계를 위해서는 기본적으로 5가지 원칙을 따르는 것이 좋다. 5가지 원칙은 각각의 앞글자를 따서 SOLID라고 부른다. 좋은 설계란 응집도는 높게, 결합도는 낮게 설계된 것을 이야기한다. - SRP (Single Responsibility Principle, 단일 책임 원칙) 객체는 단 하나의 책임만 가져야한다. 즉 어떤 변화에 의해 클래스를 변경해야 하는 이유는 오직 하나뿐이어야 함을 의미한다. - OCP (Open-Closed Principle, 개방-폐쇄 원칙) 변경에는 닫혀있고, 확장에는 열려있어야한다. 요구사항의 변경이나 추가가 발생하더라도, 기존 코드에는 수정이 일어나지 않고, 쉽게 확장할 수 있어야 한다는 의미이다. - LSP (Liskov Substitution Principle, 리스코프 치환 원칙) 자식 클래스는 부모 클래스의 역할을 대체할 수 있어야한다. 자식 클래스는 부모 클래스의 책임을 무시하거나 재정의하지 않고, 확장만 수행해야한다. - ISP (Interface Segregation Principle, 인터페이스 분리 원칙) 사용하지 않는 인터페이스는 구현하지 말아야한다. 하나의 일반적인 interface보다는 여러 개의 구체적인 interface가 낫다. - DIP (Dependency Inversion Principle, 의존 역전 원칙) ...

이 블로그의 인기 게시물

아스키 코드(ASCII)와 유니코드(unicode)

Kubernetes 학습 노트

Innovation or Threat? Why Tech Giants Are Issuing a Total Ban on OpenClaw (혁신인가, 위협인가? 테크 거물들이 오픈클로를 전면 금지하는 이유)