[Java Design Pattern] 자바 디자인패턴, Strategy 패턴(전략 패턴)

Strategy 패턴

- 여러 가지의 알고리즘을 하나의 추상적인 접근점을 만들어서 접근점을 통해 교환 가능하도록 구성하는 자바의 디자인 패턴

- 주로 게임 개발에서 무기를 교체하거나 장비를 교체하거나 할 때 사용한다고 한다.

 

Strategy 패턴을 이해하기 위해서는 두가지를 면저 알아두어야 한다.

1. 인터페이스

2. 델리게이트

 

인터페이스

- 인터페이스는 추상적인 어떤 것이다. 칼, 검, 활의 추상적인 어떤 것은 무기가 될 것이고, 신발, 바지, 상의의 추상적인 어떤 것은 장비가 될 것이다. 다른 의미로는 굉장히 의미가 다양하게 쓰이는 언어라고 생각이 들어 Strategy 패턴에서 사용하고 있는 의미로만 설명되었다.

 

델리게이트

- delegate(위임하다, 떠넘기다) 라는 영어단어로 개발 영역에서 많이 쓰인다. Strategy 패턴에서 사용되는 의미는 특정 객체의 기능을 사용하기 위해서 다른 객체의 기능을 빌려다 쓰는 방식이다. 즉, 내가(객체) 이러한 기능이 필요한데 다른 객체에 이미 같은 기능이 구현되어 있다. 그럴 때 그 객체의 기능을 빌려다가 내 기능처럼 사용하는 것이다.

 

package Starategy;

public interface Ainterface {
	//기능에 대한 선언
	public void myfunction();
}

AInterface라는 인터페이스가 있을 때, 이 인터페이스를 구현하는

package Starategy.impl;

import Starategy.Ainterface;

public class AinterfaceImpl implements Ainterface{

	@Override
	public void myFunction() {
		System.out.println("myFunction 호출");
	}

}

AinterfaceImpl이라는 클래스가 존재한다면 Ainterface를 구현하기 위해 다음과 같은 코드가 사용된다.

package Starategy;

import Starategy.impl.AinterfaceImpl;

public class Main {
	public static void main(String[] args) {
    
		Ainterface ainterface = new AinterfaceImpl();
		ainterface.myFunction();  
	
    }
}

  출력 : myFunction 호출

 

위임방식은 다음과 같다.

package Starategy;

import Starategy.impl.AinterfaceImpl;

public class AObj {
	
	Ainterface ainterface;
	
	public AObj() {
		ainterface = new AinterfaceImpl();
	}
	
	public void myFunction() {
		
		//위임한다.
		ainterface.myFunction();
		
	}
}

 

 myFunction 이라는 기능이 필요한 또하나의 AObj 객체가 있다고 할때, 이미 같은 기능을 AinterfaceImpl 클래스에 정의해두었기 때문에 AObj 객체생성을 할때 Ainterface 멤버변수에 AinterfaceImpl 객체를 담습니다. 그리고 해당 객체의 같은 기능을 AObj 클래스의 myFunction(같은 기능을 하는 메소드)에 Ainterface의 기능을 실행시킵니다.

그러면 결국은 AObj객체의 myFunction 메소드는 Ainterface 구현객체의 기능을 실행하는 것입니다. 이것을 델리게이트라고 합니다.

 

Strategy 패턴

게임개발을 한다고 하면, 게임 캐릭터는 무기(weapon)를 하나 가지고 있습니다. 무기의 행위는 공격이라는 행위가 있습니다.

 

package Starategy;

public interface Weapon {
	//무기의 행위 선언
	public void attack();
	
}
/*--------------------------다른클래스 영역이라고 가정.--------------------------*/
package Starategy;
public class GameCharacter {
	//접근점
	private Weapon weapon;
	
	//교한 가능
	public void setWeapon(Weapon weapon) {
		this.weapon = weapon;
	}
	public void attack() {
		if(weapon == null) {
			System.out.println("맨손으로 공격");
		}
		else {
			//델리게이트
			weapon.attack(); // 내가 들고있는 것에 따라서 공격이 달라진다.
		}
	}
}

sㄴ델리게이트 방식은 attack 메소드에서 사용됩니다. weapon이라는 변수는 Weapon 인터페이스를 구현하고 있는 객체가 들어있을 텐데, 그것이 검인지 활인지 총인지에 따라서 어떤 알고리즘이 수행될 지 정해지는 것입니다. 게임캐릭터의 attack 행위는 무기의 attack 행위와 같을테니까요. 

그럼 무기를 창으로 바꾸면 Spear 클래스를 만들어서 Weapon 인터페이스를 구현하여 해당 로직을 구현하는 곳에서 게임캐릭터의 weapon 객체에 Spear 객체를 할당해주면 게임캐릭터의 attack 메소드는 Spear 객체의 attack 메소드를 실행할 것입니다.

 

만약 무기를 버리면 맨손공격을 하겠네요.

 

댓글

Designed by JB FACTORY