객체지향 14

[Design Pattern] Chapter 14 기타 패턴

브리지 패턴 구현과 더불어 추상화 부분까지 변경해야 한다면 브리지(Bridge) 패턴을 쓰면 된다. 브리지 패턴을 사용하면 추상화된 부분과 구현 부분을 서로 다른 클래스 계층구조로 분리해서 그 둘을 모두 변경할 수 있다. 빌더 패턴 제품을 여러 단계로 나눠서 만들도록 제품 생산 단계를 캡슐화하고 싶다면 빌더(Builder) 패턴을 사용하면 된다. 빌더 패턴을 사용하면 여러 단계와 다양한 절차를 거쳐 객체를 만들 수 있다. 책임 연쇄 패턴 1개의 요청을 2개 이상의 객체에서 처리해야 한다면 책임 연쇄(Chain of Responsibility) 패턴을 사용하면 된다. 책임 연쇄 패턴을 사용하면 객체 사슬을 통해, 자기가 받은 요청을 검사해서 직접 처리하거나 사슬에 들어있는 다른 객체에게 넘겨 요청을 보낸 ..

[Design Pattern] Chapter 13 실전 디자인 패턴

디자인 패턴의 정의 (디자인) 패턴(Pattern)은 특정 컨텍스트 내에서 주어진 반복적인 문제의 해결책이다. 디자인 패턴 카탈로그 GoF의 23가지 패턴 카탈로그에는 다음과 같은 요소가 들어간다 패턴 이름/패턴 종류 용도(Intent): 패턴의 역할 동기(Motivation): 문제와 해결책에 관한 시나리오 적용 대상(Applicability): 패턴의 적용 대상 구조(Structure): 패턴 안의 클래스 다이어그램 구성 요소(Participant): 패턴 내 각 클래스의 역할 협동(Collaboration): 각 구성 요소의 연계 결과(Consequences): 패턴을 사용했을 때의 효과 구현(Implementation)/샘플 코드(Sample Code): 패턴을 구현하기 위한 기술과 예제 코드 사..

[Design Pattern] Chapter 12 복합 패턴

복합 패턴의 정의 복합 패턴(Compound Pattern)은 2개 이상의 패턴을 결합해서 일반적으로 자주 등장하는 문제들의 해법을 제공한다. 모델-뷰-컨트롤러(MVC) 모델-뷰-컨트롤러(Model-View-Controller, MVC)는 대표적인 복합 패턴이다. 뷰: 모델을 표현하는 방법을 제공함. 일반적으로 화면에 표시할 때 필요한 상태와 데이터는 모델에서 직접 가져옴. 컨트롤러: 사용자로부터 입력을 받으며 입력받은 내용이 모델에게 어떤 의미가 있는지 파악함. 모델: 모델에는 모든 데이터, 상태와 애플리케이션 로직이 들어있음. 뷰와 컨트롤러에서 모델의 상태를 조작하거나 가져올 때 필요한 인터페이스를 제공하고, 모델이 자신의 상태 변화를 옵저버들에게 연락해 주긴 하지만, 기본적으로 모델은 뷰와 컨트롤러..

[Design Pattern] Chapter 11 프록시 패턴

프록시 패턴의 정의 프록시 패턴(Proxy Pattern)은 특정 객체로의 접근을 제어하는 대리인(특정 객체를 대변하는 객체)을 제공한다. 프록시 패턴 UML Proxy와 RealSubject는 모두 Subject 인터페이스를 구현하며, 따라서 어떤 클라이언트에서라도 Proxy와 Subject를 똑같은 방식으로 사용할 수 있다. Proxy는 RealSubject 객체의 레퍼런스를 가지고 있으면서, RealSubject로의 접근을 제어한다. 진짜 작업을 처리해야 할 때는 RealSubject 객체 레퍼런스에게 요청 request()을 전달한다. 프록시 패턴 예제 코드 public interface Icon { public int getIconWidth(); public int getIconHeight();..

[Design Patterns] Chapter 10 상태 패턴

상태 패턴의 정의 상태 패턴(State Pattern)을 사용하면 객체의 내부 상태가 바뀜에 따라서 객체의 행동을 바꿀 수 있다. 마치 객체의 클래스가 바뀌는 것과 같은 결과를 얻을 수 있다. 상태 패턴 UML State 인터페이스는 공통 인터페이스 handle()를 정의하며, 이를 구상 클래스들이 각자의 알고리즘으로 구현한다. Context는 State를 가지고 있으며, state.handle() 메소드가 호출되면 해당 시점의 State 구상 클래스에게 작업이 위임된다. 상태 패턴 예제 코드 public interface State { public void insertQuarter(); public void ejectQuarter(); public void turnCrank(); public void ..

[Design Patterns] Chapter 09 반복자 패턴과 컴포지트 패턴

반복자 패턴의 정의 반복자 패턴(Iterator Pattern)은 컬렉션의 구현 방법을 노출하지 않으면서 집합체 내의 모든 항목에 접근하는 방법을 제공한다. 반복자 패턴 UML Iterator 인터페이스를 통해 컬렉션 순회에 대한 일관된 인터페이스를 제공하고, 이를 Aggregate 인터페이스를 구현한 ConcreteAggregate 구상 클래스가 createIterator()를 통해 ConcreteIterator 구상 클래스를 만들고, 이를 이용하여 컬렉션을 순회한다. 반복자 패턴 예제 코드 public interface Menu { public Iterator createIterator(); } public class CafeMenu implements Menu { Map menuItems = new..

[Design Patterns] Chapter 08 템플릿 메소드 패턴

템플릿 메소드 패턴의 정의 템플릿 메소드 패턴(Template Method Pattern)은 알고리즘의 골격을 정의한다. 템플릿 메소드를 사용하면 알고리즘의 일부 단계를 서브클래스에서 구현할 수 있으며, 알고리즘의 구조는 그대로 유지하면서 알고리즘의 특정 단계를 서브클래스에서 재정의할 수도 있다. 템플릿 메소드 패턴 UML 추상 클래스에 선언된 템플릿 메소드는 일련의 알고리즘을 정의하며, 일부 알고리즘은 abstract 메소드로 선언되어 있다. abstract로 선언되었던 단계들은 구상 클래스에서 구현한다. 템플릿 메소드 예제 코드 public abstract class CaffeineBeverage { final void prepareRecipe() { boilWater(); brew(); pourIn..

[Design Pattern] Chapter 07 어댑터 패턴과 퍼사드 패턴

어댑터 패턴의 정의 어댑터 패턴(Adapter Pattern)은 특정 클래스 인터페이스를 클라이언트에서 요구하는 다른 인터페이스로 변환함. 인터페이스가 호환되지 않아 같이 쓸 수 없었던 클래스를 사용할 수 있게 도와준다. 어댑터 패턴 UML 어댑터에서 타깃 인터페이스를 구현하며, 클라이언트에서 요청을 보내면 어댑터를 통해 최종적으로 어댑티에게 위임된다. 어댑터 패턴 예제 코드 public interface Duck { public void quack(); public void fly(); } public interface Turkey { public void gobble(); public void fly(); } Duck 인터페이스와 Turkey 인터페이스는 서로 다른 메소드를 가지고 있다. public..

[Design Pattern] Chapter 06 커맨드 패턴

커맨드 패턴의 정의 커맨드 패턴(Command Pattern)을 사용하면 요청 내역을 객체로 캡슐화해서 객체를 서로 다른 요청 내역에 따라 매개변수화할 수 있다. 이를 통해 요청을 큐에 저장하거나 로그로 기록하거나 작업 취소 기능을 사용할 수 있다. 커맨드 패턴의 UML 클라이언트는 커맨드 인터페이스를 구현한 구상 커맨드와, 구체화된 행동을 처리하는 리시버를 설정한 후, 이를 인보커에 저장한다. 이후 인보커를 통해 커맨드를 실행하라고 요청하면 인보커 → 구상 커맨드 → 리시버 순으로 명령을 받아. 최종적으로 리시버가 구체화된 행동을 수행한다. 커맨드 패턴 예제 코드 public interface Command { public void execute(); public void undo(); } public..

[Design Pattern] Chapter 05 싱글턴 패턴

싱글턴 패턴의 정의 싱글턴 패턴(Sinleton Pattern)은 클래스 인스턴스를 하나만 만들고, 그 인스턴스로의 전역 접근을 제공한다. 싱글턴 패턴 UML 클래스 변수에 싱글턴의 하나뿐인 인스턴스가 저장되고, getInstance() 정적 메소드를 통해서만 인스턴스를 (생성)얻을 수 있다. 멀티스레딩 문제 멀티스레드로 싱글턴에서 인스턴스가 2개 생성될 수 있다. (코드 실행 순서에 따라) 자바 애플리케이션은 대부분 멀티스레드 환경이므로, 싱글턴이 멀티스레드 환경에서도 돌아가도록 getInstance() 메소드를 동기화해야한다. 해결방법 1: getInstance() 동기화 (synchronized 사용, 호출될 때마다 동기화하므로, 성능이 100배 저하됨) 해결방법 2: 인스턴스를 시작하자마자 만드는..