'Design Patterns/내 생각'에 해당되는 글 2건

  1. 2012.10.29 Decorator 패턴에 대한 생각 정리 (1)
  2. 2012.08.01 싱글톤과 상태 값

안녕하세요.

오늘은 Decorator 패턴에 대해 생각이 정리된 부분을 이야기 해볼까 합니다.


Decorator 패턴에 대한 설명은 위의 링크를 따라 들어가서 보시면 될 것 같구요.


Decorator패턴은 굉장히 간단하고 멋져보이는 패턴입니다.

저도 처음 봤을 때 "우와~ 이런방법이 있구나~" 하면서 놀랐죠.


하지만 막상 실전에 어떻게 활용해야할 지 막막하더군요...

그래서 내린 결론은 

디자인 패턴을 이해한다는 것은 단순히 클래스 관계를 이해하는 것뿐만 아니라, 언제 어떤 의도로 이 패턴이 사용될 수 있는지를 이해하는게 더 중요하다.

라는 것 입니다.


많은 책에서 Decorator패턴을 설명할 때에 커피의 가격 계산에 대한 예를 사용하거나, 윈도우에 스크롤뷰와 프레임을 붙이는 등의 상황을 예로 듭니다. 


그런데 아무리 생각해봐도 이러한 상황에 Decorator패턴을 쓰는게 가능한지 잘 모르겠더군요.




먼저, 커피의 경우에는 Decorator패턴이 정말이지 가격 계산에만 쓰일 수 있는 것 같습니다. 즉, 커피 자체에 대해 Decorator패턴을 적용할 수 있는게 아니라, 커피의 가격에 대해서만 적용이 가능하다는 것입니다. (물론, 커피의 가격만 계산하는 프로그램이라면 전혀 문제될 것이 없지만, 커피의 향이나 색 등을 표현하기에는 Decorator 패턴만으로는 부족하다는 것입니다.)


윈도우 예의 경우에는 윈도우에 스크롤을 입힌다는데, 스크롤 뷰라는게 단순히 뷰만 있는게 아니고 윈도우 내의 컨텐츠 움직임에 따라 스크롤의 길이와 위치가 변화하게 되는데 이런 부분까지 다 표현하는게 가능할까...라는 점입니다.

(이를 Decorator패턴으로 설계 가능하다고 생각하시는 분은 저에게 가르침을 주세요~^^)




이렇게 기존의 예에 대한 이해부족으로 실제로 적용 가능한 상황이 어떤게 있을까.. 하고 생각을 해보게 되었습니다.


터치 효과 Touch Effect

제가 생각한 예는 화면을 터치했을 때 특수한 효과가 나는 예입니다. 

화면을 터치하면 진동이 나올 수도 있고, 터치한 주위로 꽃들이 터질 수도 있고, 화면이 깨지는 효과가 나올 수도 있죠.

또 이들 효과가 2개 이상 동시에 발동될 수도 있습니다.


이러한 효과가 한번에 하나만 가능하다면 Strategy 패턴같은 방법으로 구현이 가능하겠죠. 

하지만 동시에 여러가지 효과가 발동되어야 한다면 Strategy패턴으로 구현하기보다는 Decorator패턴을 이용하는게 좋을 것 같습니다. 


먼저 클래스 다이어그램부터 보시죠.




클래스 구조는 전형적인 Decorator패턴의 모습입니다.

이렇게 Decorator패턴을 이용해서 설계를 하면 생길 수 있는 장점에 대해 이야기를 해보죠.


1. 상태 변수를 이용해 프로그래밍하는 것보다 훨씬 코드가 간결해진다.

첫 번째 장점은 상태 변수를 이용해 프로그래밍하는 것보다 코드가 간결해진다는 점입니다.

즉, 터치 효과를 저장하는 int형의 멤버 변수를 만들고 이 멤버 변수에 어떤 효과들이 설정되어있는지 설정값을 담아둘 수 있습니다. 


public static final int TOUCH_EFFECT_FLOWER = 1 << 0;
public static final int TOUCH_EFFECT_CRACK = 1 << 1;
public static final int TOUCH_EFFECT_VIBRATION = 1 << 2;

private int _touchEffects = TOUCH_EFFECT_FLOWER | TOUCH_EFFECT_CRACK;


이렇게 _touchEffects 변수에 터치 효과들을 담아두고 있다가, 사용하는 곳에서 변수를 체크해서 적절한 효과를 발동시키는 겁니다. 

 

public void onTouch(float x, float y) {
    if(_touchEffects & TOUCH_EFFECT_FLOWER == TOUCH_EFFECT_FLOWER) {
        //꽃 효과를 발동한다.
    }

    if(_touchEffects & TOUCH_EFFECT_CRACK == TOUCH_EFFECT_CRACK) {
        //액정이 깨진 효과를 발동한다.
    }

    if(_touchEffects & TOUCH_EFFECT_VIBRATION == TOUCH_EFFECT_VIBRATION) {
        //진동 효과를 발동한다. 
    }
}


이렇게 사용하는 터치 효과를 발동해야 하는 곳에서 _touchEffects 변수를 체크해서 사용해야 합니다.

이렇게 사용하는 것의 단점이 뭘까요?

솔직히 복잡하게 설계를 하는 것보다 이렇게 쓰는게 훨씬 빨리 코딩할 수 있는 방법아닐까요?


지금 보여진 코드만 보면 그렇습니다.

하지만,, _touchEffects라는 변수는 여기에서만 사용되지 않을 수도 있습니다.

다른 메서드에서도 저런 분기문을 똑같이 사용할 수 있습니다.

또 효과가 하나씩 늘어날 때마다 _touchEffects 변수를 사용하는 곳의 코드를 또 추가적으로 작성해야 하구요.

그렇게 _touchEffects를 사용하는 메서드가 늘어날수록 코드는 더욱더 복잡해지고, 수정을 위해 많은 시간과 노력을 요할 수 있습니다.


2. Strategy 패턴을 이용하는 설계보다 클래스 수를 훨씬 줄일 수 있다.

만약 Decorator패턴을 사용하지 않고, Strategy패턴을 이용해 설계를 하면 이 경우에는 훨씬 많은 수의 클래스가 필요할 수 있습니다.

혹시 오해하실까봐 말씀드리는데 Strategy패턴이 Decorator패턴보다 좋지 않다는게 아니라, 지금 제가 말씀드리고 있는 이 상황에서 그렇다는 겁니다.  



먼저 이 상황을 다시 한번 설명 드리자면, 동시에 여러개의 효과가 발동될 수 있습니다.


즉, 꽃 효과와 진동효과가 동시에 발동되거나 진동효과와 액정 깨짐 효과가 동시에 발동될 수도 있습니다.

이를 Strategy패턴으로 구현하려면 TouchEffect인터페이스를 상속받는 FlowerTouchEffect, VibrationTouchEffect, CrackTouchEffect뿐만 아니라 이들을 조합한 FlowerVibrationTouchEffect, FlowerCrackTouchEffect ..등등 많은 수의 서브 클래스가 필요하게 됩니다.


정리

이렇게 수평적인 관계의 여러 기능을 동적으로 결합해야하는 경우에 Decorator패턴이 잘 사용될 수 있을 것 같습니다. 


또 다르게 사용될 수 있는 방법이 생각난다면 다음 번에 포스팅하기로 하죠~^^

저작자 표시 비영리 변경 금지
신고

'Design Patterns > 내 생각' 카테고리의 다른 글

Decorator 패턴에 대한 생각 정리  (1) 2012.10.29
싱글톤과 상태 값  (0) 2012.08.01
Posted by Code-Moon

댓글을 달아 주세요

  1. ㅁㄴㅇㄹ 2012.12.01 22:02 신고 Address Modify/Delete Reply

    잘 보고 갑니다 ^^ Decorator 패턴을 쓰면 switch문을 쓰는 것보다 재사용성하고, 유지보수가

    쉬워지는 장점이 있네요 ㅎㅎ

안녕하세요?

요즘 맨날 영어 공부와 디자인 패턴 공부를 동시에 하기 위해, 영문 위키에 있는 디자인 패턴 번역 작업만 하다가 오랜만에 제 글을 쓰네요^^



오늘은 싱글톤에 대한 제 생각을 정리해보려 합니다. (오늘 코드 수정 작업을 하다가 든 생각입니다.^^)


저는 원래 싱글톤을 자주 사용하면서도 남용하지 않으려 노력하고 있었습니다.

왜냐하면 일각에서는 싱글톤을 안티패턴의 일종으로 간주하기 때문이죠. 



분명히 써보면 굉장히 편리한 디자인 패턴인데도 불구하고, 너무나 편리한 나머지 아무곳에서나 마구마구 쓸 수 있는 만능 클래스가 될 수 있다는 우려때문에, 싱글톤을 사용하는데에 있어 조심스럽더라구요.

그러다가 cocos2d-x를 접하게 되었는데, 여기에서 싱글톤을 꽤나 잘 쓰고 있는 것 같았습니다.


일단 cocos2d는 너무나 잘 알려진 오픈소스 게임 엔진인데요, 굉장히 유명하고 많이 사용되는만큼 코드에 대한 저의 신뢰성도 높아지더군요. 그리고 실제로 오픈 소스 엔진들을 분석해보면 꽤나 좋은 설계 요소들이 많습니다.



어쨌든 이번에 프로젝트를 진행하면서 몇몇 싱글톤 클래스를 만들 필요가 있었습니다.

일단 그 클래스들을 싱글톤으로 설계한 것은 꽤 잘 된 선택이라고 생각합니다.(어쩌면 더 좋은 방법이 있었을 수도 있지만...)


그런데 문제는 싱글톤 클래스에 상태 변수를 넣으면서부터 시작되었습니다. 처음 구현을 할 때에는 그 클래스에 적당한 상태 변수라고 생각했습니다. 이 변수 값은 setter를 통해 외부에서 수정될 수 있고, getter를 통해 외부에서 값을 확인할 수 있습니다.


싱글톤 클래스에 상태변수를 넣으면 왜 문제가 될까요?



싱글톤은 모든 클래스에서 접근 가능한 클래스이자 객체입니다. 다시 말하면, 모든 클래스에서 싱글톤의 상태값을 변화시킬 수 있다는 것이죠.

이러한 특징이 처음 구현을 할 때에는 굉장히 편하게 느껴집니다. (저도 실제로 그러했습니다. 그냥 원하는 클래스에서 싱글톤에 접근해서 상태변수를 마음 껏 바꾸면 되죠.ㅎ)


예를들어, A 클래스에서 싱글톤의 상태 변수를 변화시키고, B 클래스에서는 싱글톤의 상태 변수에 따라 어떤 일을 수행하고, C 클래스에서는 싱글톤의 상태 변수에 따라 싱글톤의 상태 변수를 다른 값으로 변화시키는 등의 코드를 작성할 수 있습니다.


그런데, 이렇게 싱글톤 객체의 상태를 이용한 코드를 작성하고나서 얼마 뒤에 그 코드에 기능을 추가하던지, 기능을 변경해야하는 경우가 있다면 굉장히 머리 아픈 일이 생길 수 있습니다.


위의 예에서 B클래스는 싱글톤 상태 변수의 값에 따라 하는 일이 결정되는데, 그 싱글톤의 상태 변수는 모든 클래스에서 값을 바꿀 수 있습니다.  그래서 B클래스에서 어떤 일이 수행될지를 확인하기 위해서는 싱글톤의 상태 변수를 변화시키는 모든 코드를 살펴봐야합니다. 

싱글톤은 너무나도 자유로운 클래스이기에 어디에서 값이 어떻게 바뀌었는지 정확히 추측해내기가 쉽지 않습니다. (물론, 정말 작은 시스템이라면 문제 없을 수도 있지만, 보통의 프로젝트는 결코 작은 시스템으로 끝나지 않죠?ㅎㅎㅎ)



그래서 오늘 내린 결론은, 싱글톤을 사용할 때에는 외부에서 접근 가능한 상태 변수를 왠만해서는 사용 안하는게 미래를 위해 좋다는 것입니다.


저작자 표시 비영리 변경 금지
신고

'Design Patterns > 내 생각' 카테고리의 다른 글

Decorator 패턴에 대한 생각 정리  (1) 2012.10.29
싱글톤과 상태 값  (0) 2012.08.01
Posted by Code-Moon

댓글을 달아 주세요

티스토리 툴바