반응형
전략 패턴이란?
우리가 슈퍼를 갈 때 버스 타고 가거나, 걸어가거나, 자전거를 타고 가는 등의 여러 가지 방법이 있다.
이러한 방법으로 갈때의 길을 미리미리 알아두고 그때그때 끌리는 것으로 가곤 한다.
이처럼 프로그래밍에서도 여러가지 방법을 구현해 놓고 클라이언트가 런타임 시기에 알맞은 전략을 사용할 수 있도록 하는 것이 바로 전략 패턴이다.
전략 패턴을 사용했을 때의 장점
- 코드 중복을 줄일 수 있다.
- 기존 코드없이 새로운 전략을 추가할 수 있다.
- 런타임 시에 전략을 선택할 수 있다.
언제 전략 패턴을 고려해야 하는가?
- 여러 전략 중 한 가지의 전략을 선택해야 할 때
- 전략 알고리즘을 자주 변경 해야 할 때
상태 패턴을 사용했을 때의 단점
- 전략이 많아지면 코드가 매우 많아질 수 있다는 단점 (복잡도 상승)
- 클라이언트에서 전략을 선택해야 하므로 클라이언트 코드가 복잡해질 수 있다.
비슷한 패턴과의 비교
- 상태 패턴은 객체의 상태에 따라서 행동을 변경하는 패턴 / 전략 패턴은 알고리즘을 변경하는 것에 초점 (목적의 차이)
구현 방법
먼저 이동할 때 어떤 방법으로 이동할지를 나타내는 간략한 MoveSystem을 만들어 보자
package com.example.designpattern.behavioral.strategy.legacy;
public class MoveSystem {
public enum Strategy {
WALK, BUS, BICYCLE, CAR
}
private Strategy strategy;
public MoveSystem(Strategy strategy) {
this.strategy = strategy;
}
public Strategy getStrategy() {
return strategy;
}
public void setStrategy(Strategy strategy) {
this.strategy = strategy;
}
public void Move() {
if (strategy == Strategy.WALK) {
System.out.println("걸어 가기... 뚜벅뚜벅");
} else if (strategy == Strategy.BUS) {
System.out.println("버스 타고 가기... 삑!");
} else if (strategy == Strategy.BICYCLE) {
System.out.println("자전거 타고 가기... 따릉따릉");
} else if (strategy == Strategy.CAR) {
System.out.println("내차를 타고 가기... 부릉부릉");
} else {
System.out.println("어떻게 갈지 정하지 않았어!!");
}
}
}
package com.example.designpattern.behavioral.strategy.legacy;
public class LegacyClient {
public static void main(String[] args) {
MoveSystem moveSystem = new MoveSystem(MoveSystem.Strategy.WALK);
moveSystem.Move(); //걸어 가기... 뚜벅뚜벅
moveSystem.setStrategy(MoveSystem.Strategy.BUS);
moveSystem.Move(); //버스 타고 가기... 삑!
moveSystem.setStrategy(MoveSystem.Strategy.BICYCLE);
moveSystem.Move(); //자전거 타고 가기... 따릉따릉
}
}
디자인 패턴을 쓰지 않고 구현하게 된다면 이런 식으로 구현하게 될 것이다.
하지만 이 코드의 단점은 새로운 전략을 추가하게 된다면 기존의 코드를 수정해야 한다는 점이다.
이를 해결하기 위해서 전략 패턴을 적용시켜 보자.
package com.example.designpattern.behavioral.strategy.refactor;
public interface MoveStrategy {
void move();
}
public class WalkStrategy implements MoveStrategy {
@Override
public void move() {
System.out.println("걸어 가기... 뚜벅뚜벅");
}
}
public class BusStrategy implements MoveStrategy{
@Override
public void move() {
System.out.println("버스 타고 가기... 삑!");
}
}
public class BicycleStrategy implements MoveStrategy{
@Override
public void move() {
System.out.println("자전거 타고 가기... 따릉따릉");
}
}
public class MyCarStrategy implements MoveStrategy{
@Override
public void move() {
System.out.println("내차를 타고 가기... 부릉부릉");
}
}
먼저 각 전략들을 추상화하여 MoveStrategy 인터페이스로 추출하고 해당 인터페이스를 구현하여 각 전략별로 구현하였다.
package com.example.designpattern.behavioral.strategy.refactor;
public class MoveSystem {
private MoveStrategy moveStrategy;
public MoveSystem(MoveStrategy moveStrategy) {
this.moveStrategy = moveStrategy;
}
public MoveStrategy getMoveStrategy() {
return moveStrategy;
}
public void setMoveStrategy(MoveStrategy moveStrategy) {
this.moveStrategy = moveStrategy;
}
public void move() {
moveStrategy.move();
}
}
package com.example.designpattern.behavioral.strategy.refactor;
public class Client {
public static void main(String[] args) {
MoveSystem moveSystem = new MoveSystem(new WalkStrategy());
moveSystem.move(); //걸어 가기... 뚜벅뚜벅
moveSystem.setMoveStrategy(new BicycleStrategy());
moveSystem.move(); //자전거 타고 가기... 따릉따릉
moveSystem.setMoveStrategy(new MyCarStrategy());
moveSystem.move(); //내차를 타고 가기... 부릉부릉
}
}
이제 더 이상 전략을 새롭게 추가할 때 기존의 코드를 건들지 않고 변경할 수 있게 되었다.
반응형
'Design Pattern' 카테고리의 다른 글
디자인 패턴 (Design patterns) (0) | 2023.02.03 |
---|