변화의 비용으로 설명하는 결합(coupling)과 응집(cohesion)

최근들어 왕성한 블로깅 활동을 하고 있는 켄트 벡님의 Coupling and Cohesion을 읽고 대충 끄적.

낮은 결합도와 높은 응집도(Low coupling and high cohesion). 이 원칙은 70년대에 소개된 이래로 소프트웨어의 설계와 아키텍처 등을 평가하는데 중요한 기준으로 적용되오고 있다. 하지만 이 비슷하게 느껴지는 결합이라는 말과 응집이라는 개념은 왠만큼 설명을 들어도 사실 명쾌하게 이해되지 않아서 이해한 척 해봤자 막상 실전에서 별 도움이 안되는 것 같다.

송치형님이 번역한 Holub on Patterns(망해가는 책이라던데 안본 분이라면 절판되기 전에 사서 읽어보길…)  앞에 추가한 0장에 소개된 정의를 배껴보자면,

응집도(cohesion)는 ‘하나의 클래스가 하나의 기능(책임)을 온전히 순도 높게 담당하고 있는 정도’

결합도(coupling)는 ‘클래스간의 서로 다른 책임들이 얽혀 있는 상호 의존도의 정도’

라고 할 수 있다. 책임(기능)의 구분에 따라 차이를 나타내는 정의가 정확하다고 보지만 역시 시원하게 설명되는 느낌은 없다. 나만 그런가? 아무튼 그래서 이 낮은 결합도와 높은 응집도를 설명해야 할 일이 있을 때는 항상 얼렁뚱땅 얘기하고, 다들 아리송해하는 눈빛을 보이면 대충 넘어갔던 기억이…

 

이 응집도와 결합도에 대해서 켄트 벡은 변화의 성격과 비용이라는 개념으로 설명하고 있다. 비록 그것이 일반적인 정의는 아닐지라도 내게는 참 이해하기 쉽게 설명된 개념으로 느껴졌다.

먼저 결합도를 보자. "Coupling이란 두개의 요소에 대해서 하나의 변경이 다른 것의 변경를 요구하는 정도"라고 설명되어있다. 즉, 결합도란 변화가 전파되는 정도를 의미한다. 하나의 요소에 변화가 생겼을 때, 그것이 강하게 결합되어 있는 다른 요소들에게 파문처럼 전파되어진다면(arload님이 자주 언급하는 ripple effect) 변경에 많이 비용이 발생한다. 이것이 강한 결합이 가지는 단점이다.  물론 결합이 강하면 그만큼 변경이 일어날 가능성이 적어질 수도 있다. 비용이 비싼만큼 변경을 꺼리게 되기 때문이다. 그런면에서 결합에 대한 비용은 실제 변화가 일어 날때까지는 발생하지 않는다. 반대로 얘기하면 충분히 발생 가능한 결합 때문에 큰 비용이 요구되어지는 것이 있다면, 그 결합을 낮추는 쪽으로 설계되어지는 것이 바람직하다는 것이다.

우리는 회사가 망할 때까지 모든 시스템에서 반드시 오라클만을 사용하겠다거나, 브라우저는 천지가 바껴도 IE만 쓰겠다는 확신이 있다면 뭐 그럼 그런 DB나 브라우저에 강한 결합을 가지는 전용 기능을 사용해도 무방할 것이다. 실제로 현장에서 많이 관찰되는 그런 종류 확신이 어디서 나오는지, 얼마나 믿을 수 있는지는 모르겠지만 말이다. 반대로 DB의 종류가 자주 변경될 가능성이 있다면 DB별 dialect를 지원하는 Hibernate같은 ORM을 쓰거나 모든 DB가 다 받아들일 수 있는 표준 SQL만을 사용하는 것이 결합도를 낮추는 방법이고, 그것이 소프트웨어 개발의 가장 큰 비용이 들어가는 유지보수 기간의 실질적인 비용을 줄여줄 것이다. (IT거버넌스도 많이 한다는데, 소프트웨어 개발부터 유지보수까지 전과정의 비용관점에서 프로젝트를 평가하는 기업이 과연 많은지 궁금하다… 당장 초기 개발비용과 기간에 대한 실적에만 목매고 있는 다면.. 흠.)

그런면에서 결합이란 한가지 변화의 요구가 많은 곳에 걸처서 영향을 주는 정도로 생각하면 될것이다.

 

반면에 응집(Cohesion)이란 하나의 변화가 하나의 요소에 대해서 일어날 때 발생하는 비용으로 측정이 가능하다. “응집이란 시스템에 변경이 필요할 때 하나의 요소에서 변화하는 부분의 정도”로 설명할 수 있다. 쉽게 말하자면, 한가지 변경 요청에 대해서 변경이 일어날 때 전체가 다 같이 변하면 응집도가 높은 것이고, 작은 부분만 변경이 일어나면 응집도가 낮은 것이다. 높은 응집도가 좋은 이유는, 변화의 요청에 대한 대응이 명확해지기 때문이다. 만약 응집도가 낮아서 어떤 변경에 대해서 한 요소의 일부분만 변경이 일어나게 된다면, 그 중에서 어떤 부분이 변경이 되야 할지를 파악해야 하고, 그것이 그 변경되지 않은 부분에 정말 영향을 미치지 않았는지에 대해서도 검증을 해야 할 부담이 있기 때문이다. 변하려면 전체가 같이 변하는 것이 부분만 변경되는 것보다 비용이 적게 든다는 것이다. 보통 덩치가 큰 모듈은 이런 단점을 가진다.

이는 변경의 영역을 독립시키는 전략이라고 볼 수 있다. 따라서 메소드를 잘게 나누고, 클래스를 분리하면서 적당한 크기를 정해야 한다면 바로 이 변화가 일어 날때 영향을 미치는 정도로 판단할 수 있다.

 

그래서 이 결합과 응집은 같은 관점, 즉 발생가능한 변경에 대해서 필요한 비용이라는 측면에서 통합적으로 설명이 가능하다. 책임을 너무 잘게 쪼개면 하나의 변경에 대해서 여러개의 모듈이 동시에 변경이 일어나게 되므로 결합도가 높은 상태가 되버리고, 너무 큰 덩치로 몰아버리면 변경이 일어날때 모듈의 일부분만 바뀌는 탓에 오히려 비용이 또 올라가 버리게 된다. 결국 높은 응집도와 낮은 결합도는 서로 일정부분 영향을 주게 된다.

결국은 이 밸런스를 적절하게 유지하는 것이 핵심이다. 그것을 일어날 가능성이 있는 변화와 그에 따른 변경의 요구가 퍼저나가는, 또는 축소되는 경우를 보고 그 비용이라는 관점에서 생각해보면 판단에 도움이 될 수 있지 않을까 싶다. 어떤 특정한 설계구조, 아키텍처도 이상적일 수 없다. 각 시스템의 특성과 상황, 조건에 따라서 유연한 판단이 필요할 것이다. 다만, 변경에 대한 예측은 생각보다 쉽지 않아서 그것이 문제다. 처음부터 변화를 고려한 설계를 할 것인가, 아니면 변화가 혹시 생기면 신속하게 대응하도록 심플한 구조를 유지할 것인가 하는 문제도 있다.

 

켄트 벡은 결론에서 비용의 관점을 봤을 때 낮은 응집도(큰 모듈) 보다는 높은 결합도(여러 요소에 걸처 변화의 파문이 일게 되는 것)가 훨씬 큰 비용증가(기하급수적으로)를 보인다고 이야기 했다. 그래서 단순하게 생각하면 너무 잘게 쪼개는 것이 안좋아보이지만, 그럼에도 자기의 습관은 일반적으로 더 작게 쪼개는 것이라고 했다. 그것은 결합도를 낮출 수 있는 능력에 대한 자신감이 있기 때문이라고. 아 부러워.

 

앞으로 이런 설계와 관련된 주제에 대해서 계속 이야기를 하겠다고 하니 무척 반갑다. 며칠 사이에 벌써 몇개가 올라왔는데.. 시간 날 때마다 하나씩 꼼꼼히 읽어봐야겠다.

 

나는 개인적으로 테스트편의성(testability)의 관점에서 이를 설명하는 것도 하나의 좋은 방법이라고 생각한다. 단지 테스트를 위해서라도 적절한 응집력을 가지는 독립모듈로 구성하는 것이 충분한 가치가 있다고 본다. 예측할 수 없는 변화 때문에 어쩔 수 없는 변경의 파문과 비용이 요구 된다면, 잘 작성된 테스트가 그 비용을 낮추는데 많은 도움이 될 수 있기 때문이다. 기회가 되면 나도 한번 생각을 정리해봐야겠다.

13 Comments

손영수April 13th, 2009 at 11:33 am

앞으로도 kent beck님이 올리신 글이 있으면 종종 전달 부탁드립니다.

말씀하신대로 균형을 맞춘다는 것이 가장 중요한것 같습니다.
testability로 비용을 낮춘다는 것도 현실적인 좋은 방법이 될듯합니다. :)

그럼 좋은글 계속 부탁드려요 :)

물개April 13th, 2009 at 2:12 pm

변화의 성격과 비용의 관점에서 응집도와 결합도를 살펴본다. 꽤 흥미롭고, 개인적으로도 도움이 많이 되는 글이야. 난 응집도와 결합도 사이의 적절한 벨런스란게 운영 시점에서 찾아지는 거지, 개발 과정에서 결정되기는 어렵다고 봐. 결국 결합도와 응집도를 포함한 서비스 운영 과정의 지표를 뽑아내고, 해당 지표를 이용해서 원하는 수준까지 지속적으로 리팩토링 해나가면서 품질을 향상시킬 수 있는 체계를 만들어나가는 게 중요한거 같애. 잘 작성된 테스트가 변경를 받아들이는 마음과 그것을 실천하는 비용 측면에서 모두 큰 도움이 된다는데는 동의하지만, 그건 그 체계의 주요 구성 요소일 뿐이지 전체는 아니쟎아. 한가지 아쉬운건 대부분의 SM 조직이 한번 정착된 체계를 계속 고도화시켜서 품질을 높이고, 비용을 낮추는 일에 적극적이지 않다는 거. 결국 IT 비용의 대부분은 유지보수에서 발생하는 거 아냐? 그러다 결국 몇년이 지나고 빅뱅 방식으로 싹~다 바꾸자.. 하는 식으로 최신 기술로 포장만 바뀐 똑같은 수준의 시스템을 떼돈들여 개발하는 거. 그게 문제인거 같애.

그러니 소프트웨어 공학이 Heuristic이 녹아든 공학 대접을 못받고, 무슨 사기꾼들 철마다 헛소리 해대는 것 마냥 취급받지. 변경에 대한 비용을 통제하기 위해 낮은 결합도와 높은 응집도를 유지하는 원칙 하에 적절한 관리 방안을 찾아야 합니다? So What? 그 말한 친구는 최대한 그 원칙에 맞춰 시스템을 개발하겠지만, 그러곤 책임질 새도 없이 빠져버리쟎아. 제대로 사상이 전달안된 시스템을 운영하는 사람들은 예전의 자기 습관대로 쓸 수록 시스템을 걸레로 만들어가고 말야. 리팩토링 해서 고도화시켜 봤자, 신규/변경 SR 하나 처리하는 것보다 평가를 못받으니 그럴 수 밖에 없지. 회귀 테스트는 커녕 Smoke Test 수준도 갖추지 못했으니, 괜히 건드렸다 사고라도 나는 날엔 시말서나 쓰고 말이지..

댓글을 쓰다 보니 흥분해서 찌질한 신세한탄이나 하고 말았네. ㅋㅋ 암튼 회사 로고는 한번 생각해 볼테니까, 기대하고 있어~

TobyApril 13th, 2009 at 2:21 pm

손영수/ 실제 운영중에는 변경이 있지 않을 것 같더라도 단지 테스트작성을 위해서, 즉 mock등의 사용을 위해서라 결합도를 낮추는(분리와 인터페이스 도입) 식의, 일시적인 추가 비용을 들이는 것이 전체적인 비용면에서는 오히려 득이 될 수 있다는 얘기였습니다. 나중에 한번 자세히 풀어서 얘기해보죠.
물개/ 인기 에이스 컨설턴트 다운 날카롭고 비판(관?)적인 시각이군.

영회April 13th, 2009 at 2:53 pm

Kent Beck 옹의 글은 좋은데, 어렵단 말이야.

TobyApril 13th, 2009 at 3:01 pm

영회/ 아직 30대 중후반인 롯 존슨 군의 글은 이해하기 쉬운데 말이지?

cbiscuitApril 13th, 2009 at 4:13 pm

물개는 아직 인기 에이스 컨설턴트가 아닙니다.
단지 그렇게 되기를 바라고 있을 뿐이죠.
여러사람들이 들르는 블로그인지라, 잘못된 정보는 바로잡아야 할 것 같아서요. ^^;

TobyApril 13th, 2009 at 4:56 pm

cbiscuit/ 본인의 주장과는 다르군요.

물개April 13th, 2009 at 6:24 pm

거참.. 인기 에이스 컨설턴트, 본인의 주장? 장난이래도 오해의 소지가 있는 건 자제해줘야지. 그 버릇 제발 좀 고쳐..

TobyApril 13th, 2009 at 7:07 pm

물개/ 흠.. 발언을 녹음을 했어야 하나… 증거가 없네.

영회April 14th, 2009 at 3:35 am

물개/조심해.. 나도 종종 말꼬리 잡혀서 마치 내가 그렇게 주장한 양 광고하더라고.. ‘과장법사’ 신공에 더 이상 당하지 않게, 형도 조심해.

TobyApril 14th, 2009 at 7:25 am

영회/ 같은 회사 동료라고 협공을 하네. :(
그럼 말꼬리 잡힐 말을 하지 말았어야지.

moovaApril 14th, 2009 at 9:51 am

변화와 변경에 따른 응집과 결합을 좀 더 자세하게 생각해 주는 포스트 같습니다.

Kent Beck..에 대한 시각도 많이 배워갑니다.
전체적인 비용면에서 mock의 사용에 관한 측면 공감하구요.
testability 시각으로 변화의 비용을 정리해 주신다면 더 한번 생각하게 될 계기가 될 것 같습니다.

하지만 이런 측면들을 우리 현업에 적용하려면 아마도 교육비용만 해도 만만치 않겠네요^^

근데 몇몇분들은 같은 회사세요?
스터디 모임인줄만 알았거든요;;;

(해당내용 관심있어서 들려봤고 용기내서 커맨트 올립니다)

TobyApril 14th, 2009 at 10:11 am

moova/ 영회와 물개는 같은 회사 소속입니다.

Leave a comment

Your comment