최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday

티스토리 뷰

자동차제어 인터페이스.

 

자동차들이 있는 클래스에서 공통된 제어는 페달 부분이고, 크게 브레이크와 악셀로 나뉜다.

 

이 페달부분을 인터페이스로 각 자동차들이 구현상속을 받고, 운전자인 드라이버는 그저 페달(인터페이스)만 조작할 뿐이다.

 

자동차를 바꾸고 싶을때는, 호스트코드에서 필요에 따라 자동차의 종류만 바꾸어 주면 된다.

 

(내 실력이 실력인지라.. 상황에 맞게 예제를 코딩하였지만 코드의 확장 및 유연성이 부족함. 따라서 응용하려면 더욱 공부하는 수밖에 없다.)

 

구성은 다음과 같다.

 

자동차의 종류 - "쿠페, 레미콘, 세단" 클래스

 

자동차의 공통점 - "페달 : 브레이크, 악셀" 인터페이스

 

운전자 - "드라이버" 클래스

 

호스트 코트 - "Main" 도큐멘트 클래스

 

자동차인터페이스.zip

 

 


 

IPedal.as


package  carControls{
 
 public interface IPedal {

  // Interface methods:
  function set accelerator(speed:uint):void;
  function get accelerator():uint;
  
  function brake():void;
 }
 
}


6 : 액셀을 밟았을 때에는 속도가 조절되므로 set 메서드를 사용하였다,

     속도계를 사용하므로 데이터 타입은 0~41억의 범위를 가지고있는 양의정수 uint 타입이다.

7 : get 메서드로 속력을 리턴 받을 수 도 있다.

9 : 브레이크. 영문 표기법에 따르면 break와 brake 둘다 맞는 표현이며, break라는 예약어와 혼동을 우려해서 brake로 작성하기로 한다.

 

 

CarCoupe.as


package  carControls{
 
 public class CarCoupe implements IPedal{

  private var _speed:uint;
  
  public function CarCoupe() {
   // constructor code
  }
  
  public function set accelerator($speed:uint):void{
   _speed = $speed;
   trace(this + "의 속도는 :" + _speed);
  }
  
  public function get accelerator():uint{
   trace(this + "의 속도는 :" + _speed);
   return _speed;
  }
  
  public function brake():void{
   trace(this + "브레이크작동");
  }

 }
 
}

 

11 ~ 21 : 인터페이스에서 사용한 것 과 똑같은 형식으로 함수를 만들어준다.

 

CarRemicon.as


package  carControls{
 
 public class CarRemicon implements IPedal{
  
  private var _speed:uint;
  
  public function CarRemicon() {
   // constructor code
  }
  
  public function set accelerator($speed:uint):void{
   _speed = $speed;
   trace(this + "의 속도는 :" + _speed);
  }
  
  public function get accelerator():uint{
   trace(this + "의 속도는 :" + _speed);
   return _speed;
  }
  
  public function brake():void{
   trace(this + "브레이크작동");
  }
 }
 
}

 

레미콘의 모습. 쿠페와 동일.

 

CarSedan.as


package  carControls{
 
 public class CarSedan implements IPedal{

  private var _speed:uint;
  
  public function CarSedan() {
   // constructor code
  }
  
  public function set accelerator($speed:uint):void{
   _speed = $speed;
   trace(this + "의 속도는 :" + _speed);
  }
  
  public function get accelerator():uint{
   trace(this + "의 속도는 :" + _speed);
   return _speed;
  }
  
  public function brake():void{
   trace(this + "브레이크작동");
  }
  
 }
 
}

 

세단의 모습. 쿠페와 동일.

 

Driver.as


package  carControls{
 
 import carControls.CarCoupe;
 import carControls.CarRemicon;
 import carControls.CarSedan;
 import carControls.IPedal;
 import flash.events.EventDispatcher;
 import flash.events.Event;
 
 public class Driver extends EventDispatcher{
  
  private var _pedal:IPedal;
  public static const DRIVER_ACCELERATOR:String = "driver_accelerator";
  public static const DRIVER_BRAKE:String = "driver_brake";
  
  public function Driver($IPedal:IPedal) { //$IPedal의 데이터 타입은 IPedal이지만, 자동차객체를 받아 제어한다.
   // constructor code
   _pedal = $IPedal;
  }
  
  public function driving($speed:uint = 0):void{
   if($speed!=0){
    dispatchEvent(new Event(DRIVER_ACCELERATOR));
    _pedal.accelerator = $speed;
   }else{
    dispatchEvent(new Event(DRIVER_BRAKE));
    _pedal.brake();
   }
  }

 }
 
}

 

 

10 : 이벤트를 전파해야 하므로 EventDispatcher를 상속받았다.

13 ~ 14 : 직접 이벤트 상수를 만들어서 정의함.

16 : Driver 생성자 부분을 주의해서 보면, $IPedal 파라메터의 데이터 형이 IPedal이 되고,

     여기서 받는 데이터 값은 자동차객체를 받게 될 것이다.

     어떤 자동차가 오던지 간에 자동차의 데이터형은 IPedal이 될 것이며, Driver가 조작하는 메서드는 항상 동일할 것이다.

     이 부분이 바로 인터페이스의 핵심이다.

21 : 드라이버가 driving 메서드를 이용해서 페달을 밟아 속력이 0을 넘게되면 이벤트를 발생시킴과 동시에 IPedal의 악셀을 실행한다.

26 : 속력이 0이면 이벤트를 발생시키고 브레이크를 실행.

 

Main.as


package  {
 
 import flash.display.Sprite;
 import carControls.CarCoupe;
 import carControls.CarRemicon;
 import carControls.CarSedan;
 import carControls.IPedal;
 import carControls.Driver;
 import flash.events.Event;
 
 public class Main extends Sprite{
  
  private var _driver:Driver;
  
  public function Main() {
   // constructor code
   super();
   init();
  }
  
  private function init():void{
   if(!_driver) _driver = new Driver(new CarRemicon());
   addEvent();
   _driver.driving(0);
  }
  
  private function addEvent():void{
   _driver.addEventListener(Driver.DRIVER_ACCELERATOR, playHandler);
   _driver.addEventListener(Driver.DRIVER_BRAKE, stopHandler);
  }
  
  private function playHandler(e:Event):void{
   trace("Driver가 Accelerator을 밟았습니다");
  }
  
  private function stopHandler(e:Event):void{
   trace("Driver가 Brake를 밟았습니다");
  }
  
 }
 
}

 

 

이제 마지막으로 모든걸 사용하는 호스트클래스인 도큐먼트클래스의 모습이다.


11 : 도큐먼트 클래스는 특수한 클래스인데 DisplayObject가 되어야하므로 Sprite (혹은 MovieClip) 을 상속받아야 함에 유의.


21 : 드라이버를 정의 해주면서 동시에 레미콘 자동차 객체를 쥐어주었다. 이는 Driver.as의 생성자에 매개변수로 전달됨.


24 : 드라이버가 드라이빙을 하는데 속력을 0을 내고있다. 이는 Driver.as의 메서드에서 해당 이벤트를 전파하고


27 : 이벤트를 감지(악셀/브레이크 - 둘중하나)하면


32 ~ 38 : 해당 함수를 실행하게 될 것이다.

 

만약 드라이버가 운전할 자동차가 다르다면  _driver = new Driver(new CarSedan()); 으로 바꾸어 써도 되고,


Driver.as에 IPedal 부분에 set 메서드를 추가하여 언제든지 자동차만 바꾸게 확장하여 사용하는 방법이 있다.

 

이 자동차 인터페이스의 결과는 다음과 같다.

 


Driver가 Brake를 밟았습니다
[object CarRemicon]브레이크작동

 

댓글