스트래티지 패턴이란?
애플리케이션에서 달라지는 부분을 찾아내고, 달라지지 않는 부분으로부터
분리시켜서 캡슐화 하는 것
- 나중에 바뀌지 않는 부분에는 영향을 미치지 않으면서 바뀌는 부분만 고치거나 확장가능
- 바뀌는 부분을 뽑아내서 구현하는 클래스 집합은 유연성있게 디자인 하고 행동들을
동적으로 바꿀 수 있도록 세터 메소드도 포함하는 것이 좋다.
구현이 아닌 인터페이스에 맞춰서 구현
상위 형식에 맞춰서 프로그래밍 한다는 것을 뜻하는 것으로 꼭 자바의 인터페이스를
사용하라는 것이 아니라 인터페이스라는 개념을 지칭한다. 실제 실행시에 쓰이는 객체가
코드에 의해서 고정되지 않도록 어떤 상위형식에 맞춰서 프로그래밍 함으로써 다형성을
활용 해야 한다는 것이다. 상위형식에 맞춰서 프로그래밍 한다는 원칙은 변수를 선언할 때
보통 추상클래스나 인터페이스 같은 상위형식으로 선언해야한다. 그렇게 할 경우 객체를
변수에 대입할 때 어떤 형식이든 집어넣을 수 있다.
다형적인 형식을 사용하는 간단한 예
Animal 이라는 추상클래스가 있고 그 밑에 Dog와 Cat이라는 구상클래스가 있다고 가정
구현에 맞춰서 프로그래밍 할 경우
Dog d = new Dog();
d.bark();
변수 “d"를 Dog형식(Animal을 확장한 구상클래스)으로 선언하면
어떤 구체적인 구현에 맞춰서 코딩해야 함
인터페이스/상위 형식에 맞춰서 프로그래밍 할 경우
Animal animal = new Dog();
animal.makeSound();
Dog라는 걸 알고 있긴 하지만 다형성을 활용하여 Animal에 대한 레퍼런스를 사용

상속보다는 구성을 활용
구성이란 "A에는 B가 있다" 라는 관계로 설명 할 수 있으며 상위 클래스에서 여러 개의
인터페이스 형식의 인스턴스변수를 추가하여 합치는 것을 구성(composition)을 이용하는 것이라고 한다. 구성은 단순히 알고리즘군을 별도의 클래스의 집합으로 캡슐화할 수 있도록 만들어주는 것 뿐 아니라 구성요소로 사용하는 객체에서 올바른 행동 인터페이스를 구현하기만 하면 실행시에 행동을 바꿀 수도 있게 해준다.
예를 들면
Duck 이라는 클래스와
FlyBehavior, QuackBehavior라는 인터페이스가 있고
FlyWithWings, FlyNoWay는 FlyBehavior를 인터페이스로 하는 클래스라고 할 때
Duck 클래스는
FlyBehavior flyBehavior
QuackBehavior quackBehavior
2개의 인터페이스 형식의 변수를 선언 함으로서
FlyBehavior과 QuackBehavior 인터페이스를 캡슐화와 구성으로 사용 하고 있다.
출처 : Head First Design Patterns
디자인 패턴의 두번째! 옵저버 패턴(Observer Pattern)
옵저버 패턴이란?
한 객체의 상태가 바뀌면 그 객체에 의존하는 다른 객체들한테 연락이 가고
자동으로 내용이 갱신되는 방식으로 일대다(one-to-many)의 의존성을 정의
옵저버 패턴의 요소
주제(subject) 객체 - 데이터가 바뀌면 옵저버 객체들에게 전달,
옵저버가 될 객체의 등록 및 제거
옵저버(observer) 객체 - 주제의 데이터가 바뀌면 갱신 내용을 전달 받음

일대다 관계는 주제와 옵저버에 의해 정의되고 옵저버는 주제에 의존됨.
느슨한 결합(Loose Coupling)
느슨하게 결합되어 있다는 것은 그 둘이 상호작용을 하긴 하지만 서로에 대해
잘 모른다는 것을 의미하며 서로 상호작용을 하는 객체 사이에서는 가능하면
느슨하게 결합하는 디자인을 사용해야 함
- 느슨하게 결합하는 디자인을 사용하면 변경사항이 생겨도 무난하게 처리할 수 있는
유연한 객체지향 시스템을 구축할 수 있다(객체 사이의 상호의존성을 최소화 할 수 있기 때문)
옵저버 패턴에서는 주제와 옵저버가 느슨하게 결합되고 있는
객체 디자인을 제공
- 주제가 옵저버에 대해 아는것은 옵저버가 특정 인터페이스를 구현 한다는 것 뿐
- 옵저버는 언제든지 새로 추가 가능
- 새로운 형식의 옵저버를 추가하려고 할 때도 주제를 변경할 필요가 전혀 없음
- 주제와 옵저버는 서로 독립적으로 재사용 할 수 있음
- 주제나 옵저버가 바뀌더라도 서로에게 영향을 미치지 않음

<옵저버 패턴 클래스 다이어그램>
자바 내장 옵저버 패턴
- Observer 인터페이스와 Observable 클래스로 구현되어 있음
- 많은 기능들을 제공하고 푸시(Push)방식과 풀(Pull)방식 사용 가능
- 푸시방식은 데이터를 메소드의 인자로 전달하는 데이터 객체 형태로 전달
- 풀방식은 옵저버에서 전달받은 Observable 객체로부터 원하는 데이터를 가져가는 방식
자바 내장 옵저버 패턴의 단점
- Observable은 클래스
- 서브 클래스를 만들어야 됨(재사용성에 제약 생김)
- Observable 인터페이스라는 것이 없기 때문에 자바에 내장된 Observer API하고
잘 맞는 클래스를 직접 구현한다는 것이 불가능
- Observable 클래스의 핵심 메소드를 외부에서 호출 할 수 없음
- Observable 메소드를 살펴보면 setChanged() 메소드가 protected로 선언되어
있기 때문에 서브 클래스 에서만 호출이 가능
(상속보다는 구성을 사용한다는 디자인 원칙에 위배됨)
출처 : Head First Disign Patterns
디자인 패턴의 세번째! 데코레이터 패턴(Decorator Pattern)
데코레이터 패턴이란?
객체의 추가적인 요건을 동적으로 첨가. 데코레이터는 서브클래스를 만드는 것을 통해서
기능을 유연하게 확장 할 수 있는 방법을 제공.
OCP - 클래스는 확장에 대해서는 열려있어야 하지만
코드변경에 대해서는 닫혀있어야 한다.
기존 코드는 건드리지 않은 채로 확장을 통해서 새로운 행동을 간단하게 추가 할 수 있도록 하는 것
데코레이터 패턴의 특징
- 데코레이터의 수퍼클래스는 자신이 장식하고 있는 수퍼클래스와 같다.
- 한 객체를 여러개의 데코레이터로 감쌀 수 있다.
- 데코레이터는 자신이 감싸고 있는 객체와 같은 수퍼클래스를 가지고 있기 때문에 원래
객체(쌓여져 있는 객체)가 들어갈 자리에 데코레이터 객체를 집어넣어도 상관이 없다.
- 데코레이터는 자신이 장식하고 있는 객체에게 어떤 행동을 위임 하는것 외에
원하는 추가적인 작업을 수행할 수 있다.
- 객체는 언제든지 감쌀 수 있기 때문에 실행중에 필요한 데코레이터를 마음대로
적용할 수 있다.
<클래스 다이어그램>

커피 가격 프로그램

위와 같이 할 경우 우유나 모카 등을 추가할 경우 Milk DarkRoast, Mocha DarkRoast, Milk Espresso, Mocha Espresso 등 클래스가 엄청나게 늘어나게 됨
인터페이스와 수퍼클래스 상수를 사용할 경우

문제점 : 첨가물의 가격이 바뀔 때마다 기본 코드수정을 해야하고 첨가물의 종류가 많아지면 새로운 메소드 추가, 수퍼클래스의 cost()도 수정해야 함. 아이스티 처럼 새로운 음료를 추가 할 때 들어가지 말아야 할 첨가물이 발생해도 상속을 받게 됨
데코레이터를 사용한 커피 가격 프로그램

<클래스 다이어그램>

데코레이터를 사용하는 코드
Beverage beverage = new DarkRoast(); //DarkRoast 객체를 만듦
beverage = new Mocha(beverage); // Mocha로 감쌈
beverage = new Milk(beverage); // Milk로 감쌈
beverage = new Milk(new Mocha)); // 위 두줄을 이렇게 한줄로 나타낼 수 도 있음
자바 입출력을 할 때 늘 사용되는 자바 IO 에서도 데코레이터가 사용되고 있음
출처 : Head First Design Patterns