카테고리 없음

[헤드퍼스트 디자인패턴] 1. 전략 패턴

혀내 2022. 7. 27. 16:25
반응형

전략 패턴 (Strategy Pattern, 객체 지향 패턴)

 전략 패턴은 알고리즘 그룹을 정의하고 각 그룹을 별도 클래스로 캡슐화해서 각 그룹마다 서로 다른 알고리즘 객체로 변경할 수 있도록 도와주는 디자인 패턴입니다. 클라이언트에서 사용되는 알고리즘을 별도 클래스로 분리해 클라이언트에게 영향을 미치지 않고 독립적으로 변경할 수 있다는 장점이 있습니다.

 

 

객체 지향 디자인 원칙

책에 따르면 다음의 원칙에 따라 전략 패턴을 적용했을 때 보다 객체 지향적인 코드를 작성할 수 있습니다.

 

1. 애플리케이션에서 달라지는 부분을 찾아내고, 달라지지 않는 부분과 분리한다.

코드에서 수시로 바뀔 수 있는 부분은 따로 다른 클래스로 뽑아서 캡슐화합니다.

바뀔 수 있는 부분을 분리하면, 바뀌지 않는 부분에 영향을 미치지 않고도 그 부분만 수정하거나 또는 확장할 수 있습니다.

 

2. 구현보다는 인터페이스에 맞춰서 프로그래밍 한다.

 여기서 말하는 인터페이스는 중의적인 의미를 가집니다.

 

의미 1. 자바의 구조( = Java의 Interface)

의미 2. 상위 형식에 맞춰 프로그래밍하는 행동( = 인터페이스, 추상 클래스, 부모 클래스)

 

 

달라지는 부분에 대한 책임은 클라이언트가 아닌 다른 클래스에 위임하도록 합니다.

그리고 기존 클래스에서 달라지는 부분에 대한 클래스 변수를 선언할 때, 어떤 구현 클래스도 넣을 수 있도록 추상 클래스, 인터페이스와 같은 상위 형식으로 선언해 사용하도록 합니다.

 

3. 상속보다는 구성을 활용한다.

- 상속: "A는 B이다."

- 구성(Composition): "A에는 B가 있다."

 

객체지향의 특징에 '상속'이 있기는 하지만, 상속에는 장점만큼 단점도 많답니다 :)..

상속으로 클래스를 분리하면 사용하지 않는 부모 클래스의 메소드도 모두 오버라이딩해 구현해야 한다는 귀찮음이 있습니다.

그래스 가급적이면 달라지는 부분에 대한 별도 클래스를 생성할 때에는 구성을 활용하도록 합니다.

 

 

 

전략 패턴의 구조

출처: https://refactoring.guru/ko/design-patterns/strategy

 

1. Context: 우리가 전략 패턴을 적용할 기존 코드

  • 전략의 상위 클래스 변수를 선언하면 사용할 전략 구현 클래스를 손쉽게 변경하거나 확장할 수 있습니다.

 

2. Strategy: 하나의 행동을 의미하는 전략 인터페이스

  • Context는 Strategy 인터페이스의 메소드를 호출해 행동을 수행할 수 있습니다.
  • Strategy 인터페이스를 상속하여 구체적인 행동을 정의할 수 있습니다

 

3. ConcreteStrategy: Strategy 인터페이스를 상속해 실제 구체적인 알고리즘을 구현한 클래스

  • ex) MoveStrategy 인터페이스를 상속해 RunStrategy, WalkStrategy, FlyStrategy 등의  클래스를 구현할 수 있습니다.

 


예시)

꽥꽥 소리를 내는 오리의 추상 클래스 Duck

public abstract class Duck {
    // 꽥꽥 소리를 내는 행동은 어떤 오리냐에 따라 달라질 수 있어 다른 클래스로 분리
    QuackBehavior quackBehavior;
    
    public void performQuack() {
    	quackBehavior.quack();
    }
}

 

꽥꽥 소리를 내는 행동에 대한 인터페이스 QuackBehavior

public interface QuackBehavior {
	public void quack();
}

 

꽥꽥 소리를 내는 행동 인터페이스 QuackBehavior의 구현 클래스

public class PlainQuack implements QuackBehavior {
    public void quack() {
    	System.out.println("꽥");
    }
}

public class MuteQuack implements QuackBehavior {
    public void quack() {
    	System.out.println("조-용");
    }
}

public class SQuack implements QuackBehavior {
    public void quack() {
    	System.out.println("삑");
    }
}

 

Duck의 구현 클래스

public class MallardDuck extends Duck {

    public MallardDuck() {
        // "꽥" 소리를 내는 행동 구현 클래스 주입
    	quackBehavior = new PlainQuack();
        
        // "조-용" 소리를 내는 행동 구현 클래스 주입
        // quackBehavior = new MuteQuack();
        
        // "삑" 소리를 내는 행동 구현 클래스 주입
        // quackBehavior = new SQuack();
    }
    
    public void display() {
    	System.out.println("저는 물오리입니다.");
    }
}

 


 

 

참조:

 

헤드 퍼스트 디자인 패턴(개정판)

유지관리가 편리한 객체지향 소프트웨어 만들기! “『헤드 퍼스트 디자인 패턴(개정판)』 한 권이면 충분합니다!”

m.hanbit.co.kr

 

반응형