본문 바로가기

공부/컴퓨터

[디자인패턴] State 패턴

반응형
==========================================================================
이 글은 이론적으로 아는 것을 직접 설명 및 구현을 해 봄으로써 제 자신의
실력을 다지기 위한 글 입니다. 물론 정확한 이론. 용어도 아님을 밝힙니다.
이 글을 직.간접적으로 사용함으로써 발생되는 모든 불이익을 책임지지 않습니다.

문의점, 오류, 잘못된 용어들은 저의 홈페이지 Work 게시판을 이용하여 주시고
이상의 사항에 대하여는 최대한 덧글 ( 코멘트 ) 를 이용해 주십시오.

본 글은 저의 홈페이지인 http://ggaman.com 과
싸이월드의 (JPSC) JAVA program study club 에서 보실수 있습니다.

homepage : http://ggaman.com e-mail n MSN : chan at ggaman.com

20040217 - Chan
==========================================================================

안녕하세요.
찬 입니다.

디자인 패턴을 오랜만에 다시 하나 해 보네요 ..

그동안 너무 많이 놀아서 공부를 해야 하는데.. 쩝 ;; 이것저것 아무것도 잡히지 않고.
JPSC 에 들어왔다가... 아 -_-! 하고. 하나 시작해 봅니다 ^_^

오늘 알아볼 디자인 패턴은 State 패턴 입니다.

한글로 하면 상태 패턴이겠죠? 상태를 이용한 패턴?

디자인 패턴의 거의 모든것은 사용하고자하는 어떤것을 추상화를 시켜서..
추상화된 인터페이스를 가지고 객체를 다루고자합니다.
( 제 짧은 견식으로는 이제까지 보아왔던 거의 모든 패턴들이 그랬습니다. )

아마도 다음과 같이 되어 있지 않을까요?
상태를 나타내는 interface 나 abstract 클래스(A)가 있고.
그것을 상속 받는 실제 클래스(B,C)들이 있을것입니다.

이제 어떠한 작업을 할려고 할때에는 A 클래스의 참조를 이용해서 모든 메소드를 사용합니다.
물론 A 클래스의 참조에는 B나 C의 객체가 들어 있을것입니다.

즉 A는. 그냥 단지 쓰기만 하고, 나중에 A참조가 가르키고 있는 객체가
B 일 때에는 B가 오버라이딩한 메소드를 사용하고,
C 일 때에는 C가 오버라이딩한 메소드를 사용하게 되겠죠.

아마도 그럴것입니다. ( 이제까지 봐 왔던 모든것들이 그랬듯이 ;; )


그럼 예제를 하나 살펴 보겠습니다.
제가 가지고 있는 책 ( Java 언어로 배우는 디자인 패턴 입문, 영진닷컴 )에서는 다음과 같은 예제들이 있네요.



경비시스템클래스 {
        금고사용시호출되는메소드() {
                if (주간) {
                        경비센터에 이용기록;
                } else if (야간) {
                        경비센터에 비상사태 통보;
                }
        }

        일반통화시호출되는메소드() {
                if (주간) {
                        경비센터호출;
                } else if (야간) {
                        경비센터자동응답기호출;
                }
        }
}


위의 예제를 보면.. 야간, 주간에 각기 사용되어야할 메소드가 아주 많이 있다면
if 와 else if 로.. 코드를 아주 지저분하게 하는 소스가 될것입니다.
지금 공부하는 이 State 패턴을 알기 전이라면,
저같은 놈은 당연히 저렇게 사용하는것이 당연한것처럼 보입니다.

하지만 State 패턴을 이용하면 생각보다 깔끔한 소스를 만들수 있습니다.


위에 A, B, C 클래스의 예를 들면서 만들었던것을 한번 말로 만들어 보죠.


저기 A 클래스가 아마도 상태를 나타내는 클래스가 되겠고,
A를 상속 받은 B와 C가 주간, 야간을 나타낼것입니다.
그리고 A는 두가지 메소드의 프로토타입을 선언(interfrace로 작성)할것이고,
B,C에서는 각각 두가지의 메소드의 하는일을 구현하게 되겠죠?


직접 한번 만들어 보죠.


// 상태를 나타태는 인터페이스
interface State {
        open();
        tel();
}

// 주간을 나타내는 클래스
class Day implements State {
        open() {
                경비센터이용기록;
        }
        tel() {
                경비센터호출;
        }
}

// 야간을 나타내는 클래스
class Night implements State {
        open() {
                경비센터에비상사태통보;
        }
        tel() {
                경비센터자동응답기호출;
        }
}



그렇다면 이것을 어떻게 쓸까?

위에 말했다시피 아마도 State 참조를 만들어서, Day, Night 객체를 생성해서 물리겠죠?
다형성을 이용하기 위해서는 아마도 다음과 같이 쓰겠죠?

State s1 = new Day();
State s2 = new Night();


그러면 이제 각각 주간과 야간을 나타내는 객체인 a1 과 a2가 만들어졌습니다.
( 물론 이 a1 과 a2는 A 형의 참조를 가지고 있죠. )



이제 하나 빠진게 있죠?
바로.. 금고를 나타내는 클래스.. 를 만들어 보죠 ^_^


// 금고 클래스
class CashBox {

        State s;        // 현재 상태를 나타내는 필드.

        // 현재 상태를 지정하는 메소드
        setState(State s) {
                this.s = s ;
        }

        // 금고열기
        openCashBox() {
                a.금고사용시호출되는메소드();
        }

        // 전화하기
        tel() {
                a.일반통화시호출되는메소드();
        }
        
                
}



그럼 실행하는 클래스를 만들어볼까요?

public StateMain {
        public static void main(String[] args) {

                State day = new Day();
                State night = new Night();
                        

                CashBox cb = new CashBox();

                // 주간 상태로 바꿈.                
                cb.setState(day);
                // 주간상태에 금고를 염.
                cb.openCashBox();


                // 야간 상태로 바꿈.
                cb.setState(night);
                // 야간 상태에서 금고를 염.
                cb.openCashBox();

        }
}


자. 끝났습니다.

이 예제는 책에 있는것과는 다릅니다. 제가 이글을 쓰면서 임의로 만들어서 틀린 내용이 있을 수 있습니다.
( 물론 틀린 내용에 대하여 검증을 해본것도 없습니다. ;; 글을 쓰면서 즉석에서 만든거라 ;; )
그리고 책에서는 Singleton 패턴이라던지 다른 패턴들과 같이 사용한 내용이 있는데,
위에 나오는 소스는 제가 생각하기에 State 패턴과 관련되는 내용만을 추려서 작성한 것입니다.


State 패턴은 많은 if ~ else if ~ 문을 깔끔하게 없애 버립니다.
( 물론 Java에서 다형성이 가능하기 때문에 그런것이겠지요 )


원래라면 if ~ else if ~ 문등으로 감싸져서 처리되어야할 부분들이,
각각 Day와 Night 클래스로 나누어져서 작성해 버렸습니다.
그리고 State interface 를 통해서 동일한 인터페이스로. 두 가지를 모두 컨트롤 할수 있게 됩니다.

다시 말하면 if ~ else if ~ 로 감싸져야할 상태(주간인지, 야간인지)들을,
클래스로 작성해서, 좀더 알아 먹기 쉬운, 그리고 사용하기 쉬운(State 참조를 이용해서 사용) 코드를
만들어 낸다는게.. 이 패턴의 주 목적인것 같습니다.



횡설수설 어려운 말이네요 ;;
전 책을 보면서 그나마 조금 이해 했다고 생각하는데.
제 글 실력이 없어서 글을 보시는 분이 제대로 이해할지는 의문이네요 ^_^

이 글을 보고 이해가 되지 않는다면,
다른곳에서 State 패턴에 대하여 알아 보시기 바랍니다.


그럼이만,
즐거운 하루 되세요~~!!
반응형