[디자인패턴 수업 3주차 2차시] Strategy pattern

Jin Hur·2021년 9월 14일
0
post-custom-banner

Strategy pattern


intro

Pet: 추상 클래스, Dog/Cat: 상속받은 자손 클래스

객체지향에서 가장 큰 특성 중 하나인 '다형성'을 통해 Pet 참조변수로 Dog, Cat 인스턴스를 참조할 수 있다. 그리고 'cry()'라는 공통된 인터페이스를 사용할 수 있다.

cf) 메서드 오버라이딩

상속받은 메서드는 자손 클래스에 표시하지 않음.
하지만 display() 경우 메서드 오버라이딩을 한 것이므로 추상 메서드 표시가 아닌 것으로 자손 클래스에 표기.


문제의 형태


그렇다고 무작정 상위 분류(Duck)에 속하는 것들을 파생 클래스(MallarDuck, RedHeadDuck, ..)로 선언하면 문제가 발생할 수 있다. fly()라는 상위 클래스에서 정의된 인터페이스가 의미가 없는 파생 클래스가 있기 때문이다. 바로 못나는 오리(RubberDuck)가 그 예이다.

이를 어떻게 해결할 수 있을 까?

방법1.


날 수 있는 오리들에 해당하는 파생 클래스들에서 fly() 메서드(기능)을 추가하는 것이다. 하지만 이는 클라이언트 코드에서 추상 클래스를 의존하고 있는 상황(DIP)에서 fly 기능을 활용하지 못하는 문제가 발생할 수 있다. 결국 구체 클래스에 의존해야만 하는 상황이 발생할 수 있다.

방법2.


추상 클래스로 선언하고, RubberDuck의 경우 fly()를 날지 못하는 형태로 오버라이딩할 수 있다.
하지만 '날지 못하는' 종류의 오리가 추가될 때마다 날지 못하는 방식으로의 추가 구현을 계속 한다는 것은 귀찮은 일이 될 수 있다.

방법3.


상위 클래스에서 일반 메서드로 선언하고, 날지 못하는 오리 클래스에서 (날지 못하는 방식으로)오버라이딩할 수 있다.
하지만 이 또한 '방법 2'와 마찬가지로 '날지 못하는' 종류의 오리가 추가될 때마다 추가 구현이 필요하다.

방법4. strategy pattern (intro..)

전략적으로 따로 '나는(fly) 기능'을 독립적으로 빼 놓을 수 있다. 이것이 '전략 패턴(strategy pattern)'이다.

  • Fly 인터페이스
  • WingFly와 HandFly는 특정 전략(나는 방식)에 해당하는 클래스.

'정렬 기능' 예시

만약 돈을 내야한다면 sortingMethod 타입 변수(참조 변수)에 QuickSort 인스턴스 생성하고,
돈을 내도 되지 않다면 '' BubbleSort 인스턴스 생성한다.
이 후 sort() 메서드에서 독립시킨 기능의 메서드를 참조 변수를 통해 호출한다.

post-custom-banner

0개의 댓글