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

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

cf) 위키피디아 정의


  • Fly 인터페이스: 외부에서 동일한 방식으로 호출하여 해당 기능을 수행하게 함.
    - Strategy: 인터페이스나 추상 클래스로 선언

  • WingFly, HandFly 클래스: Fly 인터페이스에서 명시한 기능을 구현한 클래스들.

  • Duck 클래스: 본인의 멤버, 참조변수를 통해 Strategy 패턴을 이용함.


    필요에 따라 동적으로 구제척인 기능(전략)을 바꿀 수 있도록 setter 메서드 제공.



구체적 예시

reference: https://gmlwjd9405.github.io/2018/07/06/strategy-pattern.html
로봇 클래스 활용과 OCP 원리 지키기

// 로봇 추상 클래스
public abstract class Robot {
    private String name;
    // 기능에 해당하는 참조변수
    private AttackStrategy attackStrategy;
    private MovingStrategy movingStrategy;

    
    public Robot(String name){
    	this.name = name;
    }
    public String getName(){
        return name;
    }
    
    // 추상 메서드 
    //public abstract void attack();
    //public abstract void move();
    // => 파생 클래스에 기능 구현을 맡기지 않는다.
   
   	// 생성 시 또는 별도의 설정 함수를 통해 설정되는 '행동' 객체를 통해 공격 또는 이동을 수행한다.
    // 이를 통해 파생 클래스 구현 시 행동에 대한 추가 구현의 부담을 줄일 수 있다. 
    public void attack() { attackStrategy.attack(); }
	public void move() { movingStrategy.move(); }
    
    // 기능을 할당할 setter 메서드
    // Robot클래스와 strategy 클래스 간의 관계는 '집약 관계', 로봇 객체가 메모리에서 사라진다 해도 strategy 객체는 사라지지 않음.
    public void setAttackStrategy(AttackStrategy attackStrategy) {
        this.attackStrategy = attackStrategy;
    }
    public void setMovingStrategy(MovingStrategy movingStrategy) {
        this.movingStrategy = movingStrategy;
    }
    
}

// 로봇 클래스를 상속받는 태권V 클래스
public class TaekwonV extends Robot {
    public TaekwonV(String name){
        super(name);	// 부모 클래스의 매개변수 존재 생성자 활용
    }
    // 추상 메서드 구현(오버라이딩)
    //public void attack(){
    //    System.out.println("I have Missile");
    //}
    //public void move(){
    //    System.out.pringln("I can only walk");
   	//}
    // => 기능을 파생 클래스에서 구현하지 않는다. 
}

// 로보 클래스를 상속받는 아톰 클래스
public class Atom extends Robot {
    public Atom(String name){
        super(name);
    }
    //public void attack(){
    //    System.out.println("I have strong punch");
    //}
    //public void move(){
    //    System.out.println("I can fly");
    //}
    // => 기능을 파생 클래스에서 구현하지 않는다. 
}

// Attack strategy 인터페이스
interface AttackStrategy { public void attack(); }
// 구체적인 클래스
public class MissileStrategy implements AttackStrategy {
  public void attack() { System.out.println("I have Missile."); }
}
public class PunchStrategy implements AttackStrategy {
  public void attack() { System.out.println("I have strong punch."); }
}

// Moving strategy 인터페이스
interface MovingStrategy { public void move(); }
// 구체적인 클래스
public class FlyingStrategy implements MovingStrategy {
  public void move() { System.out.println("I can fly."); }
}
public class WalkingStrategy implements MovingStrategy {
  public void move() { System.out.println("I can only walk."); }
}


// 클라이언트에서의 사용
public class Client {
	public static void main(String[] args) {
  		Robot taekwonV = new TaekwonV("TaekwonV");
  		Robot atom = new Atom("Atom");

  		/* 수정된 부분: 전략 변경 방법 */
        // 각 구체 로봇 객체에 전략 종류에 맞는 기능(행위)를 주입한다. 
  		taekwonV.setMovingStrategy(new WalkingStrategy());
  		taekwonV.setAttackStrategy(new MissileStrategy());
  		atom.setMovingStrategy(new FlyingStrategy());
  		atom.setAttackStrategy(new PunchStrategy());

  		/* 아래부터는 동일 */
  		System.out.println("My name is " + taekwonV.getName());
  		taekwonV.move();
  		taekwonV.attack();

  		System.out.println()
  		System.out.println("My name is " + atom.getName());
  		atom.move();
  		atom.attack();
	}
}
post-custom-banner

0개의 댓글