헤드퍼스트 디자인패턴 1. 전략 패턴스터디2024. 10. 3. 10:29
Table of Contents
도입
소프트웨어 개발 불변의 진리
- 어떤 프로그래밍 언어로 어떤 개발을 하든 변하지 않는 것은 소프트웨어는 변화한다는 사실
이 장에서 소개한 디자인 원칙들
이 원칙들을 지키는 방향으로 오리 시뮬레이션 게임을 리팩토링한다
- 애플리케이션에서 달라지는 부분을 찾아내 캡슐화하고, 달라지지 않는 부분과 분리한다
- 코드 변경 과정에서 의도치 않게 발생하는 일을 줄이며 시스템의 유연성을 향상시킬 수 있다
- 구현보다는 인터페이스에 맞춰서 프로그래밍한다
- 구현체를 참조하거나, 클라이언트에서 직접 구현하지 않는다
- 클라이언트는 인터페이스만 참조
- 다시말하면, ‘상위 형식에 맞춰서 프로그래밍한다’ 는 뜻
- 상속보다는 구성(composition)을 활용한다
오리 시뮬레이션 게임에 추가된 요구사항
- 다른 게임회사를 날려버리기 위해
Duck
을 날 수 있게 만들어라!
1. 상속을 통한 해결 → 문제 발생!
- 갑자기 게임에서 러버덕 (고무 오리) 가 날아다닌다
- 즉, 상속을 통해 코드를 재사용한다고 생각했지만 날아다니면 안되는 오리에도
fly()
가 추가되어 문제가 발생
- 날지(
fly
) 못하거나, 소리낼(quack
) 수 없는 오리의 메서드를 오버라이드 해주어야 함
2. FunctionalInterface 를 통한 해결
- 날지 못하는 오리가 날아다니는 문제는 해결했지만, 코드를 재사용하지 않으므로 변경 발생 시 모든 구현체를 수정해야 하는 문제 발생
- 자바 8부터 추가된 default method를 사용하면, 행동의 기본 값은 정의해둘 수 있겠지만 행동의 구현체가 여러 개일 경우 이 방법도 한계가 존재
오리 시뮬레이션 게임에서 변화하는 부분 뽑아내기
달라지는 부분 추출 & 인터페이스화
Duck
클래스에서나는 행동
과꽥꽥거리는 행동
을 추출하여 캡슐화Duck
안에 숨겨지 있지 않으므로 다른 형식의 객체에서도 아래 행동들을 사용할 수 있다- 기존 클라이언트(
Duck
등)를 수정하지 않고도 행동 방식을 수정할 수 있다
오리의 행동 통합하기 (composition)
Duck
이 추출한행동
의 인터페이스를 필드로 갖도록 한다
- 완성된
Duck
클래스 예시
public abstract class Duck {
FlyBehavior flyBehavior;
QuackBehavior quackBehavior;
public Duck() {}
public void performFly() {
flyBehavior.fly();
}
public void performQuack() {
quackBehavior.quack();
}
...
}
동적으로 행동 지정하기
- setter 등을 사용하면 실행 중에
Duck
의 행동을 변경할 수도 있다- 행동 인터페이스의 구현체를 갈아끼운다
public abstract class Duck {
FlyBehavior flyBehavior;
QuackBehavior quackBehavior;
public Duck() {}
public void setFlyBehavior(FlyBehavior flyBehavior) {
this.flyBehavior = flyBehavior;
}
public void setQuackBehavior(QuackBehavior quackBehavior) {
this.quackBehavior = quackBehavior;
}
public void performFly() {
flyBehavior.fly();
}
public void performQuack() {
quackBehavior.quack();
}
...
}
전체 구조
전략패턴
알고리즘을 정의하고 캡슐화해서 각각의 알고리즘군을 수정해 사용할 수 있게 해준다.
전략 패턴을 사용하면 클라이언트로부터 알고리즘을 분리해서 독립적으로 변경할 수 있다.
'스터디' 카테고리의 다른 글
헤드퍼스트 디자인패턴 3. 데코레이터 패턴 (0) | 2024.10.22 |
---|---|
헤드퍼스트 디자인패턴 2. 옵저버 패턴 (0) | 2024.10.09 |
@gmelon :: gmelon's greenhouse
백엔드 개발을 공부하고 있습니다.