노무현 대통령 배너

Command Pattern 커맨드 패턴을 액션스크립트로 컨버팅 – Head First Design Pattern

by on 6.18, 2009, under Design Pattern

remote_controller헤드퍼스트 디자인 패턴의 제 6 장 커맨드 패턴 입니다. 커맨드 패턴은 객체지향 프로그래밍에서 가장 중요한 패턴 중 하나이므로 최소한의 커맨드 패턴을 적용하여 개념에 대한 이해를 돕는 포스트로부터 시작하여 차근차근 단계를 밟아 몇개의 포스트로 나눠서 작성 하겠습니다. 이 포스트는 그 중 가장 간단한 형태의 커맨드 패턴에 대해 다룹니다.

먼저 커맨드 패턴에 대한 정의를 보겠습니다.

커맨드 패턴 – 커맨드 패턴을 이용하면 요구 사항을 객체로 캡슐화 할 수 있으며, 매개변수를 써서 여러 가지 다른 요구 사항을 집어넣을 수도 있습니다. 또한 요청 내역을 큐에 저장하거나 로그로 기록할 수 도 있으며, 작업취소 기능도 지원 가능합니다.

본문 예제에서는 리모컨을 이용하여 홈 오토메이션을 구현하는 내용을 다루고 있습니다.

커맨드 객체는 모두 같은 인터페이스를 구현 해야 합니다. 커맨드 메서드이기 때문에 메서드 이름은 excute() 가 적당하겠네요.

0
1
2
3
4
5
6
package 
{
	public interface ICommand
	{
		function execute():void
	}
}

그리고 Light 구상 클래스 입니다. 불을 켜고 끄는 기능이 부여 되어있네요.

0
1
2
3
4
5
6
7
8
9
10
11
12
13
package 
{
	public class Light
	{
		public function on():void 
		{
			trace( "불 켜짐" )
		}
		public function off():void 
		{
			trace( "불 꺼짐" )
		}
	}
}

다음은 커맨드 인터페이스를 구현하는 LightOnCommand 클래스 입니다.

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package 
{
	public class LightOnCommand implements ICommand
	{
		private var light:Light;
 
		public function LightOnCommand( $light:Light )
		{
			this.light = $light;
		}
 
		public function execute():void
		{
			light.on();
		}
	}
}

생성자에서 Light 객체를 받아 인스턴스 변수로 저장하고 excute() 가 호출되면 객체 내부의 on() 메서드를 호출 하는 역할을 합니다.
불을 켜고 끄려면 LightOffCommand 클래스도 있어야 겠습니다. 포스트 본문에 보여지지 않는 코드들은 가장 아래에서 다운로드 받을 수 있습니다.

그럼 리모컨 클래스를 살펴보겠습니다.
SimpleRemoteControl 객체는 버튼 하나짜리 리모컨이라고 생각하면 됩니다. 다만 그 버튼에 여러가지 커맨드를 할당하고 해지하면서 기능을 실행 하는 것이죠.

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package 
{
	public class SimpleRemoteControl
	{
		private var slot:ICommand;
 
		public function setCommand( $command:ICommand ):void
		{
			slot = $command
		}
 
		public function buttonWasPressed():void
		{
			slot.execute();
		}
	}
}

불을 켜는 프로세스를 잠깐 살펴보면, Light 객체를 생성자로 받은 LightOnCommand 객체를 다시 SimpleRemoteControl 에서 setCommand() 메서드를 이용해 슬롯에 장전하고, buttonWasPressed() 메서드를 이용해 실행하고 있는거네요.

호스트 코드에서는 이렇게 사용 합니다.

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package 
{
	import flash.display.Sprite;
 
	public class Main extends Sprite 
	{
		public function Main():void 
		{
			var remote:SimpleRemoteControl = new SimpleRemoteControl();
			var light:Light = new Light();
			var garageDoor:GarageDoor = new GarageDoor();
			var lightOn:LightOnCommand = new LightOnCommand( light );
			var garageOpen:GarageDoorOpenCommand = new GarageDoorOpenCommand( garageDoor );
 
			remote.setCommand( lightOn );
			remote.buttonWasPressed(); //출력 : 불 켜짐
			remote.setCommand( garageOpen );
			remote.buttonWasPressed(); //출력 : 차고 문 열림
		}
	}
}

위에서 설명한대로 호스트 코드에서는 리모컨과 필요한 구상 객체를 만들고 커맨드 객체에 구상 객체를 할당 합니다. 다시 커맨드 객체를 리모컨 객체에 세팅 한 후 커맨드 객체를 실행 하고, 커맨드 객체는 구상 객체의 메서드를 실행하는 구조를 가지고 있습니다. 문장으로 써 놓고 보면 뭔가 복잡해 보이지만 실제로 코드를 실행해 보면 쉽게 이해할 수 있는 구조로 되어 있죠.

요컨대 구상객체에 직접 명령을 내리지 않고, 중간 매개체인 커맨드 객체가 대신 처리하게 하도록 명령을 캡슐화 한 것입니다. 이렇게 하면 호스트 코드에서는 어떤 기능이 리모컨에 할당되어 있는지 관계 없이 명령을 실행할 때는 커맨드 메서드인 excute() 만 호출하면 되겠죠.

Command (simple) Pattern Example 액션스크립트 코드 다운로드 (152)
이 글을 복사해서 퍼가시는건 허용하지 않습니다. 글의 주소를 다른곳에 알려주시는 것은 환영합니다.

관련된 글

:, , , , , , , , , , ,

Leave a Reply

Looking for something?

Use the form below to search the site:

Still not finding what you're looking for? Drop a comment on a post or contact us so we can take care of it!

Meta