노무현 대통령 배너

Adapter Pattern 어댑터 패턴을 액션스크립트로 컨버팅 – Head First Design Pattern

by on 5.14, 2009, under Design Pattern

Head First Design Pattern제가 참여하고 있는 스터디에서 교재로 사용하고 있는 오라일리/한빛출판사에서 발간된 Head First Design Pattern 입니다. 스터디에 대한 이해도를 높이고자 어댑터 패턴에 관한 자바 코드를 액션스크립트 코드로 컨버팅해 보았습니다.

책에는 어댑터 패턴을 이렇게 정의하고 있습니다.

“어댑터 패턴(Adapter Pattern) – 한 클래스의 인터페이스를 클라이언트에서 사용하고자 하는 다른 인터페이스로 변환합니다. 어탭터를 이용하면 인터페이스 호환성 문제 때문에 같이 쓸 수 없는 클래스들을 연결해서 쓸 수 있습니다.”

호스트코드에서 어떤 특정한 구상 클래스를 인터페이스를 통해  사용하고 있는 상황에서, 새로운 구상 클래스의 요건이 생겨서 제 3의 클래스가 생겼습니다. 이 때 호스트코드와 인터페이스의 코드는 변경하지 않고 (게다가 동일한 사용 방법으로) 제 3의 구상클래스의 메소드도 추가 사용할 수 있도록 해주는 패턴이라 할 수 있겠습니다.

IDuck 인터페이스 입니다. 책에서는 Duck 이지만 인터페이스임을 확실히 하기 위해 Duck 앞에 I를 붙였습니다.

0
1
2
3
4
5
6
7
package
{
	public interface IDuck
	{
		function quack ():void;
		function fly ():void;
	}
}

IDuck 을 구상하는 MallardDuck(물오리) 클래스 입니다.

0
1
2
3
4
5
6
7
8
9
10
11
12
13
package
{
	public class MallardDuck implements IDuck
	{
		public function quack():void
		{
			trace( "꽥!" )
		}
		public function fly():void
		{
			trace( "날고 있어요~" )
		}
	}
}

새로 등장한 ITurkey (칠면조) 인터페이스 입니다.

0
1
2
3
4
5
6
7
package
{
	public interface ITurkey
	{
		function gobble():void;
		function fly():void;
	}
}

ITurkey 인터페이스를 구상하는 WildTurkey 클래스 입니다.

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
package
{
	public class WildTurkey implements ITurkey
	{
		public function gobble():void
		{
			trace( "골골~" )
		}
 
		public function fly():void
		{
			trace( "조금밖에 못날아요" )
		}
	}
}

이렇게 두개의 구상 클래스[01] 는 각자 하는 일이 다르지만 어떠한 요구에 의해 호스트코드에서 WildTurkey 를 MallardDuck 과 동일하게 사용해야 하는 경우가 생겨버렸습니다.

이런경우에 아래와 같이 IDuck 인터페이스를 구현한 TurkeyAdapter 클래스를 이용해 ITurkey 인터페이스를 구상한 WildTurkey 객체를 감싸서 MallardDuck처럼 보이도록 변장을 시킬 수 있습니다.

0
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
package
{
	public class TurkeyAdapter implements IDuck
	{
		private var turkey:ITurkey;
 
		public function TurkeyAdapter ( $turkey:ITurkey )
		{
			this.turkey = $turkey
		}
 
		public function quack():void
		{
			turkey.gobble();
		}
 
		public function fly():void
		{
			for ( var i:int = 0; i < 5; i++ )
			{
				//칠면조가 어댑터로 실행된 것을 구분하기 위해 오리흉내(5번 짧게 날기) 를 냅니다.
				turkey.fly();
			}
		}
	}
}

아래와 같이 호스트코드 [02]  에서는 생성한 WildTurkey 객체를 TurkeyAdapter로 한번 감싸서, 오리류(IDuck) 전용의 testDuck 메서드에 던지고 MallardDuck의 메서드인 quack() 과 fly() 메서드명을 사용하지만, WildTurkey의 gobble() 과 fly() 메서드를 실행하게 할 수 있습니다.

0
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
package
{
	import flash.display.Sprite;
 
	public class Main extends Sprite
	{
		public function Main():void
		{
			var duck:MallardDuck = new MallardDuck();
			var turkey:WildTurkey = new WildTurkey();
			var turkeyAdapter:IDuck = new TurkeyAdapter( turkey );
 
			trace( "n칠면조가 말함" );
			turkey.gobble();
			turkey.fly();
 
			trace( "n오리가 말함" );
			testDuck( duck );
 
			trace( "n칠면조 어댑터가 말함" );
			testDuck( turkeyAdapter );
		}
 
		private function testDuck( $duck:IDuck ):void
		{
			$duck.quack();
			$duck.fly();
		}
	}
}
호스트코드의 실행 결과 입니다.

호스트코드의 실행 결과.

이 호스트 코드를 실행하면 왼쪽 trace문을 볼 수 있습니다.

참고로 testDuck( turkeyAdapter ); 에 오리로 감싼 칠면조를 인자로 던지지 않고 testDuck( turkey ); 칠면조를 직접 던지면 컴파일 에러가 발생합니다. 컴파일러의 입장에서는 testDuck( $duck:IDuck ); 메서드는 인자를 오리로 던지라는데 칠면조를 던졌으므로 type casting 에러가 발생하게 되는 것이죠.

Adapter Pattern Example 액션스크립트 코드 다운로드 (137)

rubber_duck_sea_by_whispering_hills

이런 광경이 연상됩니다.

이 글을 복사해서 퍼가시는건 허용하지 않습니다. 글의 주소를 다른곳에 알려주시는 것은 환영합니다.
  1. MallardDuck 과 WildTurkey 를 말합니다. []
  2. 도큐먼트 클래스를 말합니다 []

관련된 글

:, , , , , , , , , ,

4 Comments for this entry

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