Design Patterns2008. 5. 6. 17:57
객체지향 설계 원칙 5-1 OCP(Open-Close Principle) 개방 폐쇄 원칙

원리

첫번째 원칙인 개방-폐쇄의 원칙이다.
무엇을 개방하고 무엇을 폐쇄한다는 것일까 ? 이것을 한마디로 표현하는 말이 있다.
"Should be Open for Extension, but Closed for Modification" (확장에는 개방하고 수정에는 폐쇄하라)

이렇게 말하면 또 이해가 안간다 ㅡㅡ 나는 용어에 참 약하다.
그래서 좋은 예를 하나 훔쳐왔다. 핸드폰 이야기 ...

예전에 핸드폰 충전잭은 핸드폰 마다 각기 달랐다 그래서 핸드폰을 새로 구입하면 충전기도 무용지물이 되었다. 그러다 핸드폰 충전잭이 24핀으로 통일 되었다. 그래서 이제는 충전기 하나만 구입하면 핸드폰을 새로 구입해도 그대로 사용할 수 있게 되었다. 그럼 여기서 무엇이 확장이고 무엇이 수정일까 ?
확장은 핸드폰의 종류이다. 어떠한 종류의 핸드폰이라도 24핀 충전기 하나면 OK 이다. 그러면 수정은 무엇일까 ? 수정은 충전핀이다. 이제는 모든 핸드폰의 충전 단자를 24핀으로 만들어야 한다.

좋은 예가 되었나 ? 더 와닿는 예를 생각해 봤는데 ... 쩝 ...

방법

자 그럼 이제 뜬구름 잡는 얘기는 그만 두고 실제로 적용 방법을 알아보자
먼저 OCP 원칙에 의한 설계를 하려면 변화지 않는것과 변하는것을 최대한 엄격히 구분지어야 한다. (사실 말은 쉽게 하지만 이부분은 정말 어렵고 잘 안되는 부분이다.) 그리고 나서 변하는것을 개방(Open) 하고 변하지 않는것을 Close(폐쇄) 하여야 한다. 이것이 무슨 말이냐 하면 변하는 것에 대해서는 변화하는 것은 변화가 쉽게 유연하게 설계하고 변화 하지 않는것은 변하는 것에 영향을 받지 않도록 설계 해야 한다.

그럼 이러한 것들을 유연하게 하려면 도데체 어떻게 해야 하는 것일까 ? 그 답은 추상화와 다형성에 있다.
이렇게 말하면 또 와 닿지 않는다. ㅡㅡ 샘플로서 알아보도록 하자.

% OCP 를 가장 잘 표현한 패턴은 Command 패턴이다.

시나리오

스타 크래프트 라는 게임을 모두 알것이다.
게임에서  SCV, 질럿, 저글링 등 모든 유닛들은  마우스로 선택한 다음 이동하려고 하는 목표 지점에 마우스로 선택하면 선택한 지점으로 이동한다.

이 기능을 구현해야 한다고 생각해 보자.

먼저 단계를 나누자
1, 유닛 선택: 특정 유닛을 마우스로 선택한다.
2, 위치 지정: 유닛이 선택된 상태에서 이동을 원하는 위치로 마우스 클릭 한다.
3, 유닉 이동: 각 종류(질럭, SCV, 저글링 등등)의 유닛별로 선택된 위치로 이동한다.

간략하게 그림으로 그려보자
사용자 삽입 이미지

그림으로 보면 일단 마우스로 유닛을 선택하여 다른 위치로 이동 시키는 부분은 모두 동일하다.
수정이 불필요한 구간이라는 것이다. 이 구간은 폐쇄(Close)해야 한다.

그러면 유닛이동에서 하단 부분은 개방(Open) 되어있다. 왜 그럴까 ?
그것은 유닛별로 이동 속도가 다르고 지상유닛은 걸어가고 비행유닛은 날라가고 각각 행동이 틀리다.
그래서 개방(Open)된 구간에서는 변경이 되어야 하는 구간인 것이다.

그러면 개방(Open) 된 부분의 클래스 구성도로 살펴 보자.
사용자 삽입 이미지
간략하게 그려보면 위 그림과 같을 것이다.
물론 Move 메소드 이외에 새로운 메소드가 추가로 필요하다면 CUint 클래서도 변경이 되겠지만 일단은
유닛이동만 생각하기로 하자.

OCP 는 추상화, 다형성이 중요하다고 말한것을 기억하는가 ? 바로 위에 써 놓았다.
이것이 바로 추상화와 다형성을 보여주는 간단한 샘풀이다.

% C++ 개발자 이면서 아직도 Vitual 키워드를 잘 모른다면 여태까지 객체지향을 제대로 사용하지 않았을 가능성이 높다. 지금이라도 확실히 알고 넘어가길 바란다.

결론

허접한 설명과 허접한 샘플을 만들어 보았다.

다시 정리해 보자면 OCP 에 맞게 설계를 하려면 변하는 것과 변하지 않는것을 먼저 구분하고, 어느 정도까지 추상화 시킬지를 결정해야 한다. 말은 아주 쉽다. ㅡㅡ  
그러나 이 간단한 원리를 잘 적용하기 위해서는 많은 경험이 필요하다. 그냥 막 되는대로 코딩의 경험이 필요한것이 아니라 작은 일이라도 먼저 생각해서 설계하는 경험이 중요하다는 말이다.


 
Posted by 상현달