스트래티지를 활용하면 알고리즘을 사용하는 클라이언트와는 독립적으로 알고리즘을 변경할 수 있다. 어떤 객체를 만들 때 객체가 가지는 기능들이 다양하게 존재할 것 이다. 이러한 기능들을 추상화 하여 언제든지 적용할수 있게 만드는 것이다. 즉 기능을 부품화 하는 것이다. 예를 들어 포니와 그랜저 자동차가 있다. 포니에 들어가는 기어 연결부분과 그랜저에 들어가는 연결부분이 동일하다고(추상화) 하면, 저급기어, 중급기어, 고급기어를 만들어 두고 상황에 따라서 적당한 기어를 적용할수 있을것 있다. 즉 포니에는 저급기어를, 그랜저에는 고급기어를 적용하는 것이다. 이렇게 기능을 부품화하여 구조를 만드는 것을 스트레티지라고 생각하시면 된다.
프로그램 설계 구조.
- 로봇 모양은 팔, 다리, 머리, 몸통으로 이루어져 있다.
- 모든 로봇은 기본적으로 걷고, 달릴 수 있어야 한다.
- Super로봇은 날수 있고, 미사일을 쏠 수 있으며, 레이저 검을 가지고 있다.
- Standard 로봇은 날수는 없지만 미사일을 쏠 수 있다. 그리고 레이저 검은 없지만, 목검은 가지고 있다.
- Low 로봇은 날수도 없고, 미사일을 쏠 수도 없다. 그리고 레이저검 또는 목검도 없다.
먼저 로봇의 액션 즉, 움직임, 미사일, 검 등을 정의 해줄것이다.
FireAction.java(interface)
package com.javalec.robot.actions;
public interface FireAction {
public void fire();
}
먼저 각각 다르게 정의할 수 있게 인터페이스를 만들어 주었다.
FireNo.java
package com.javalec.robot.actions;
public class FireNo implements FireAction {
@Override
public void fire() {
System.out.println("미사일 발사 기능 없습니다.");
}
}
FireOk.java
package com.javalec.robot.actions;
public class FireOk implements FireAction {
@Override
public void fire() {
System.out.println("미사일 발사");
}
}
미사일을 쏠 수 있는지 없는지에 대해 추상메소드인 fire을 받아 재정의 하였다.
FlyAction.java(interface)
package com.javalec.robot.actions;
public interface FlyAction {
public void fly();
}
마찬가지로 날기 기능에대한 인터페이스를 만들어주었다.
FlyNo.java
package com.javalec.robot.actions;
public class FlyNo implements FlyAction {
@Override
public void fly() {
System.out.println("날수 없어요");
}
}
FlyOk.java
package com.javalec.robot.actions;
public class FlyOk implements FlyAction {
@Override
public void fly() {
System.out.println("날수 있어요.");
}
}
KnifeAction.java(interface)
package com.javalec.robot.actions;
public interface KnifeAction {
public void knife();
}
위와 같은 구조이다.
KnifeNo.java
package com.javalec.robot.actions;
public class KnifeNo implements KnifeAction {
@Override
public void knife() {
System.out.println("검이 없습니다.");
}
}
KnifeWithLazer.java
package com.javalec.robot.actions;
public class KnifeWithLazer implements KnifeAction {
@Override
public void knife() {
System.out.println("레이저 검을 사용 합니다.");
}
}
KnifeWithWood.java
package com.javalec.robot.actions;
public class KnifeWithWood implements KnifeAction {
@Override
public void knife() {
System.out.println("목검을 사용 합니다.");
}
}
이제 모든 동작에 대한 코딩은 끝났다. 각각 로봇들을 구현해보자.
Robot.java(interface)
package com.javalec.robot;
import com.javalec.robot.actions.FireAction;
import com.javalec.robot.actions.FlyAction;
import com.javalec.robot.actions.KnifeAction;
public abstract class Robot {
public FlyAction flyAction;
public FireAction fireAction;
public KnifeAction knifeAction;
public Robot() {
}
public abstract void shape();
public void actionFly() {
flyAction.fly();
}
public void actionFire() {
fireAction.fire();
}
public void actionKnife() {
knifeAction.knife();
}
public void actionBasic() {
System.out.println("팔, 다리, 머리, 몸통이 있습니다.");
}
public void setFlyAction(FlyAction flyAction) {
this.flyAction = flyAction;
}
public void setFireAction(FireAction fireAction) {
this.fireAction = fireAction;
}
public void setKnifeAction(KnifeAction knifeAction) {
this.knifeAction = knifeAction;
}
}
Robot 인터페이스를 만들어 각각 기능들을 재정의 하게 만들었다.
CheapRobot.java
package com.javalec.robot;
import com.javalec.robot.actions.FireNo;
import com.javalec.robot.actions.FireOk;
import com.javalec.robot.actions.FlyNo;
import com.javalec.robot.actions.FlyOk;
import com.javalec.robot.actions.KnifeNo;
import com.javalec.robot.actions.KnifeWithLazer;
import com.javalec.robot.actions.KnifeWithWood;
public class CheapRobot extends Robot {
public CheapRobot() {
flyAction = new FlyNo();
fireAction = new FireNo();
knifeAction = new KnifeNo();
}
@Override
public void shape() {
System.out.println("기본적으로 팔, 다리, 머리, 몸통으로 이루어져 있습니다. 그리고 걷고, 달릴 수 있습니다.");
}
}
StandardRobot.java
package com.javalec.robot;
import com.javalec.robot.actions.FireOk;
import com.javalec.robot.actions.FlyNo;
import com.javalec.robot.actions.FlyOk;
import com.javalec.robot.actions.KnifeWithLazer;
import com.javalec.robot.actions.KnifeWithWood;
public class StandardRobot extends Robot {
public StandardRobot() {
flyAction = new FlyNo();
fireAction = new FireOk();
knifeAction = new KnifeWithWood();
}
@Override
public void shape() {
System.out.println("기본적으로 팔, 다리, 머리, 몸통으로 이루어져 있습니다. 그리고 걷고, 달릴 수 있습니다.");
}
}
SuperRobot.java
package com.javalec.robot;
import com.javalec.robot.actions.FireOk;
import com.javalec.robot.actions.FlyOk;
import com.javalec.robot.actions.KnifeWithLazer;
public class SuperRobot extends Robot {
public SuperRobot() {
flyAction = new FlyOk();
fireAction = new FireOk();
knifeAction = new KnifeWithLazer();
}
@Override
public void shape() {
System.out.println("기본적으로 팔, 다리, 머리, 몸통으로 이루어져 있습니다. 그리고 걷고, 달릴 수 있습니다.");
}
}
이제 모든 로봇의 설계는 끝났다. 로봇 모두 Robot 인터페이스를 상속 받는다. 그것을 다시 재정의 해주면 되는 것이다.
MainClass.java
package com.javalec.robot;
public class MainClass {
public static void main(String[] args) {
System.out.println("SuperRobot이 주문 들어 왔어요. 만들어 주세요.");
Robot superRobot = new SuperRobot();
superRobot.shape();
superRobot.actionBasic();
superRobot.actionFly();
superRobot.actionFire();
superRobot.actionKnife();
System.out.println();
System.out.println("StandardRobot이 주문 들어 왔어요. 만들어 주세요.");
Robot standardRobot = new StandardRobot();
standardRobot.shape();
standardRobot.actionBasic();
standardRobot.actionFly();
standardRobot.actionFire();
standardRobot.actionKnife();
System.out.println();
System.out.println("CheapRobot이 주문 들어 왔어요. 만들어 주세요.");
Robot cheapRobot = new CheapRobot();
cheapRobot.shape();
cheapRobot.actionBasic();
cheapRobot.actionFly();
cheapRobot.actionFire();
cheapRobot.actionKnife();
System.out.println();
}
}
출력
SuperRobot이 주문 들어 왔어요. 만들어 주세요.
기본적으로 팔, 다리, 머리, 몸통으로 이루어져 있습니다. 그리고 걷고, 달릴 수 있습니다.
팔, 다리, 머리, 몸통이 있습니다.
날수 있어요.
미사일 발사
레이저 검을 사용 합니다.StandardRobot이 주문 들어 왔어요. 만들어 주세요.
기본적으로 팔, 다리, 머리, 몸통으로 이루어져 있습니다. 그리고 걷고, 달릴 수 있습니다.
팔, 다리, 머리, 몸통이 있습니다.
날수 없어요
미사일 발사
목검을 사용 합니다.CheapRobot이 주문 들어 왔어요. 만들어 주세요.
기본적으로 팔, 다리, 머리, 몸통으로 이루어져 있습니다. 그리고 걷고, 달릴 수 있습니다.
팔, 다리, 머리, 몸통이 있습니다.
날수 없어요
미사일 발사 기능 없습니다.
위 처럼 출력되는 것을 볼 수 있다. 이것이 바로 스트레티지 패턴이다. 기능들을 부품화 시켜 필요할 때 가져다 쓰는 것이다.
간단하게 스트레티지 패턴에대해 알아보았다. 매우 자주 사용되는 패턴이기때문에 꼭 짚고 넘어가야 하는 것 같다. 나도 모르게 설게하다보면 이 패턴을 쓸 때가 많다.