블로그 이미지
개발자의 조건은 어떤것도아닌 3일은 기본으로 날샐수있는 체력과 3일을 안씻어도 찝찝합을 못느끼는 것과 라면을 먹어도 탈없는 위입니다.
DefineJAVA

공지사항

최근에 받은 트랙백

글 보관함

calendar

      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29      

'Strategy Pattern'에 해당되는 글 2

  1. 2007/02/13 Strategy Pattern #2
  2. 2007/02/09 Strategy Pattern #1

Strategy Pattern #2

2007/02/13 11:19 | Posted by DefineJAVA
크리에이티브 커먼즈 라이선스
Creative Commons License

Strategy Pattern #2



스트래티지 패턴 두번째 시간이다.
우선 저번에 필자가 냈던 문제를 생각해보자~
1. 개발자는 로봇 게임을 제작중이다.
2. 게임을 더 재밋게 하기 위하여 개발자는 특수기능을 넣을려고 한다.
3. 현재는 특수기능이 "날 수 있는 기능" 밖에 없지만 이후에는 여러가지 기능이 추가 될 수도 있다.

해결방법으로 생각했던 상속을 사용하게 되면 현재 날아다니는 기능은 구현이 가능하나 나중에 특수기능이 더 많이 추가 된다면 문제가 발생한다.
그리고 또 오버라이딩을 한다면 로봇 수가 늘어 나게 될 때 개발자는 죽도록 노가다 코딩을 해야 될 것 이다.

이제 조금 더 쉽게 이 문제를 해결할 수 있는 방법을 생각 해 보자.
필자는 이 문제의 해답은 인터페이스를 잘 사용하므로써 해결 가능하다고 생각했다.(원래 답을 알고있으니....-_-)

이 것을 확실히 알아야 한다. 지금 추가하려고 하는것은 특수 기능이다. 특수 기능 중 한가지가 "날아다니는 기능" 이다.
여기서 생각할 수 있는 것은 특수기능이라는 틀을 만들고 그 안에 "날아다니는 기능"을 넣으면 된다는 것이다.

자 클래스 다이어그램을 보면 쉽게 이해 할 수 있을것이다.

사용자 삽입 이미지

아하~ 하고 이해가 오는 사람은 객체지향 개념을 알고 있는 사람일 것이다. "이게 머야?" 또는 "이렇게 해봣자 코드가 늘어나는 것은 같잖아" 이렇게 생각하는 사람은

아직 객체지향을 잘 이해하지 않고 있다.
자! 다이그램을 보면 AbilityBehavior라는 인터페이스를 Fly라는 클래스가 Implement 하고 있다. 이것이 의미하는것은 AbilityBehavior라는 큰 모델이 있고 그 모델이

할 수있는 일(Method)를 구현해야 된다는것과 AbilityBehavior ability = new Fly(); 이런식으로 선언이 가능하다는 것이다.

이쯤되면 스트래티지 패턴이 어떤 문제점을 해결 할 수있는 패턴인지 알 수 있을것이다.
특수기능에 숨는 기능을 넣어 보자.
AbilityBehavior 인터페이스를 Hide라는 클래스가 상속 받아 구현 하면 될것이다.

이제 문제점이 해결 되었는가? (모르겠으면 소스를 보는 것이 이해에 도움이 될듯 싶다);

이와 같이 구현을 한다면 로봇 객체를 선언할 때 각 로봇에 특수 기능을 줄수있다. 물론 특수 기능 변경을 하는 setAbilityBehavior라는 메소드를 만들어서 동적으로도 변경을 할 수있다.

전체적인 소스코드를 첨부 해서 올리니 한번씩 봐보길 바라며 끝으로 어떻게 하면 더욱더 적용이 가능할지 생각해보길 바란다.

디아블로같은 게임을 생각해 보아도 좋다. 갑옷이라는 인터페이스를 만들고 그 갑옷을 Implement한 클래스만 입을수 있다.
이것도 스트래티지 패턴을 이용해서 구현이 가능하다. 조금만 더 생각해 보면 알 수 있을 것이다.
set갑옷 이라는 메소드만 한개 만들어서 갑옷을 바꿔주면 된다.

일이 밀려서 몇일간 한가지를 쓰다보니 말이 앞뒤가 안 맞는 부분이 많아 졌다. 아마도 디자인패턴을 공부하려는 사람 정도면 소스만 보고도 이해 할 수 있을거라 생각한다~

// 소스
package strategy;

public interface AbilityBehavior {

  public void setName(String name);
  public void ability();
}

package strategy;

public class Fly implements AbilityBehavior {

  public String name;
  public void setName(String name) {
   // 어빌리티 이름을 지정.
   this.name = name;
  }

  public void ability() {
   System.out.println("날기시작합니다.");
  }
}

package strategy;

public class Hide implements AbilityBehavior {

  public String name;
  public void setName(String name) {
   this.name = name;
  }

  public void ability() {
   System.out.println("숨었다~ 안보이지룽-.-");
  }
}

package strategy;

public abstract class Robot {
 
  String name;
  AbilityBehavior ability;
 
  public abstract void display();
 
  public void turn(int rec) {
   System.out.println(name + "로봇이 "+rec+"만큼 돌았습니다.");
  }

  public void attack() {
   System.out.println(name + "로봇이 공격합니다.");
  }

  public void move(int x, int y) {
   System.out.println(name + "로봇이 "+x+","+y+" 좌표로 이동합니다.");
  }

  public Robot(AbilityBehavior ability, String name) {
   this.ability = ability;
   this.name = name;
  }
 
  public void performAbility() {
   ability.ability();
  }
 
}

package strategy;

class TaekwonVRobot extends Robot{

  public TaekwonVRobot(AbilityBehavior ability)
  {
   super(ability, "마징가Z");
  }
 
  public void display() {
   System.out.println("저는 " + name + " 로봇이랍니다.");
  }
}

package strategy;

class MajinggaRobot extends Robot{
 
  public MajinggaRobot(AbilityBehavior ability)
  {
   super(ability,"마징가Z");
  }
 
  public void display() {
   System.out.println("저는 " + name + " 로봇이랍니다.");
  }
}

package strategy;

class FreedomRobot extends Robot{
 
  public FreedomRobot(AbilityBehavior ability)
  {
   super(ability , "프리덤");
  }
 
  public void display() {
   System.out.println("저는 " + name + " 로봇이랍니다.");
  }
}

package strategy;

public class RobotMain
{

 public static void main(String[] args)
 {
  Robot robot1 = new FreedomRobot(new Fly());  // 날아다니는 프리덤.
  Robot robot2 = new FreedomRobot(new Hide()); // 숨는기능의 프리덤.
 
  Robot robot3 = new TaekwonVRobot(new Fly()); // 숨는기능의 태권 V.
  Robot robot4 = new MajinggaRobot(new Hide()); // 숨는기능의 마징가.
 
  robot1.display();
  robot1.performAbility();
 
  robot2.display();
  robot2.performAbility();
 
  robot3.display();
  robot3.performAbility();
 
  robot4.display();
  robot4.performAbility();
 }

}

'Define Designing > Design Patterns' 카테고리의 다른 글

Strategy Pattern #2  (0) 2007/02/13
Strategy Pattern #1  (0) 2007/02/09

Strategy Pattern #1

2007/02/09 17:51 | Posted by DefineJAVA
크리에이티브 커먼즈 라이선스
Creative Commons License

Strategy Pattern



스트래티지 패턴이란 각각의 기능을 하는 클래스를 캡슐화하여 이것을 교환하여 사용할 수 있도록 만드는 역활을 한다.
즉 현재 사용하고 있는 기능(클래스)를 동적으로 변경하여 적용 시킬 수 있다.

간단하게 예를 들자면 로봇 게임이 있다고 하자. (갑자기 http://www.defineyou.net/ 에서 본 로롯코드가 생각나서....)
이 로봇게임에는 여러가지 종류의 로봇이 나온다. 이 여러 종류의 로봇을 제작하기 위해서는 Robot 이라는 클래스를 상속 받아서 제작한다.

사용자 삽입 이미지
Robot Class에는 다음과 같은 기능이 있다.
 turn(); 돌고 도는 메소드
 move(); 이동을 하는 메소드
 attack(); 공격을 하는 메소드

각 로봇에는 display(); 라는 모양을 뿌려주는 메소드가 존재한다.

로봇게임 개발자는 로봇게임을 더 재밋게 발전 시키기 위해서 모든 로봇에 특수기술인 "날아다니는 기능"을 넣을려고 한다.
이 기능은 로봇이 하늘에서도 싸울 수 있는 기능을 하게 제작하여야한다.

당신이라면 이 문제를 어떻게 해결하겠는가?

사용자 삽입 이미지

쉽게 생각해 본다면 Robot이라는 상위클래스(슈퍼클래스)에 ability(); 라는 메소드를 만들어 날아다니는 기능을 구현하면 될것이다.
모든 로봇들은 Robot Class를 확장(상속)하여 사용하기 때문에 이렇게 한다면 아주 쉽게 해결 할 수가 있다.

로봇게임 개발자는 또 다시 생각을 해 보았다.
"태권V 로봇은 너무 강하니깐 하늘을 날아다니는 기능을 없애야 겠어"
자 모든 로봇들이 상속을 받은 Robot클레스에서는 ability();라는 메소드가 구현되어 있다.

어떤가? 이제 머리 아프게 생각을 해볼때가 됐다. Robot이라는 클래스를 상속 받기 때문에 Robot의 기능을 모두 가지고 있다.
당신이라면 이 문제를 어떻게 해결하겠는가?

ability(); 라는 메소드를 Overloading 하면 된다고 생각하는 사람도 많이 있을 것이다.
Overloading으로 이 문제 해결될 수 있지만 만약 이 프로그램이 발전되어 로봇의 종류가 100가지가 넘고 특수기능의 종류가 많아 졌다고 생각해보자!

개발자는 정말 안구에 습기차도록 노가다를 해야 될 것이다.

어떻게 하면 이 문제를 해결 할 수 있을까? 조금은 생각해 보는것이 좋을 꺼 같다.
다음차 블로그에 이 문제에 대한 해결책을 올리도록 하겠다.
그 안에 열심히 생각을 해 바란다.^ㅡ^

'Define Designing > Design Patterns' 카테고리의 다른 글

Strategy Pattern #2  (0) 2007/02/13
Strategy Pattern #1  (0) 2007/02/09
이전 1 다음