스트래티지 패턴이란?
같은 종류의 작업을 하는 알고리즘을 정의하고
각 알고리즘을 캡슐화, 그리고 알고리즘들을 서로 바꿔 사용할 수 있도록 한다.
알고리즘을 사용하는 클라이언트로부터 독립적을 알고리즘을 바꿔서 적용시킬 수 있도록 한다.
말이 너무 어렵다.
널리 알려져 있는 유명한 예시를 보자
오리라는 클래스를 만들고 이것을 상속받는 여러 오리들을 만들어 보자
class Duck {
void quack() {
System.out.println("quack");
}
void swin() {
System.out.println("swimmin");
}
void fly() {
System.out.println("flying");
}
void display() {
System.out.println("Duck");
}
}
class MallardDuck extends Duck {
@Override
void display() {
System.out.println("MallardDuck");
}
}
class RubberDuck extends Duck {
@Override
void quack() {
System.out.println("squeak");
}
@Override
void display() {
System.out.println("RubberDuck");
}
@Override
void fly() {
System.out.println("cannot fly");
}
}
Duck 클래스를 상속받아 MalladrdDuck과 RubberDuck을 만들었다.
문제는 무엇일까?
RubberDuck은 장난감 오리여서 날 수가 없지만 상속을 받아 fly라는 메서드를 가지게 된다.
해결방안?
위 코드는 오버라이드를 하여 날 수 없음을 표현하였다.
오버라이드 하는 것이 좋은 선택일까?
만약 수십 개의 날지 못하는 오리 장난감이 있다면 각각 오버라이드를 해주어야 한다.
매우 비효율적인 작업이다.
fly메서드와 quack메서드를 가지는 interface를 만들면 어떨까?
class Duck {
void swim() {
System.out.println("swimming");
}
void display() {
System.out.println("Duck");
}
}
interface Flyable {
void fly();
}
interface Quackable{
void quack();
}
class MallardDuck extends Duck implements Flyable, Quackable{
void display() {
System.out.println("MallardDuck");
}
public void quack() {
System.out.println("quack");
}
public void fly() {
System.out.println("flying");
}
}
class RedheadDuck extends Duck implements Flyable, Quackable{
void display() {
System.out.println("RedheadDuck");
}
public void quack() {
System.out.println("quack");
}
public void fly() {
System.out.println("flying");
}
}
class RubberDuck extends Duck implements Quackable{
public void quack() {
System.out.println("squeak");
}
void display() {
System.out.println("RubberDuck");
}
}
RubverDuck은 Flyable을 상속받지 않아서 문제가 해결된 것 같다.
하지만 다른 문제가 있다.
RedheadDuck 클래스와 MallardDuck 클래스는
quack 메서드와 fly 메서드를 반복해서 작성해줘야 돼 비효율적이다.
default 메서드를 생각해볼 수 있다.
하지만 default 메서드에 변화나 오류가 있다면 default메서드를 사용하는 모든 부분을 찾아 수정해 주어야 한다.
스트래티지 패턴
상황마다 수정이 필요한 부분과 그렇지 않은 부분으로 나눈다.
위 오리 클래스중 오리들마다 바뀌는 부분은 flt와 quack 부분임으로
이 두 부분을 분리하여 클래스 만듭니다.
특정 행동을 Duck 클래스에서 구현하는 것이 아니라 독립적으로 새로운 클래스를 만들어서 구현하고
Duck 클래스는 클래스나 구현한 인터페이스를 사용하여 Duck과 무관하게 만들어집니다.

'Java' 카테고리의 다른 글
| BigInteger (0) | 2021.11.03 |
|---|---|
| 옵저버 패턴(Observer Pattern) (0) | 2021.09.23 |