favor object composition over class inheritance의 두 가지 해석
Favor object composition over class inheritance.
GoF의 Design Patterns에 '이 책의 두 번째 객체 지향 설계 원칙'이라고 제시된 문구입니다. 이 문구의 해석에 대해 흥미로운 주장(이하 '그 주장')이 있습니다.
일반적으로 favor A over B는 B보다는 A를 선호한다는 뜻입니다. 따라서 위의 문구는 다음과 같이 번역할 수 있습니다.
클래스 상속보다는 객체 합성을 선호하라.
Design Patterns의 한국어판에는 '클래스 합성보다 객체 합성이 더 낫다'로 되어 있다고 하는데 '클래스 합성'은 '클래스 상속'의 오타라고 역자분이 밝히셨습니다. '선호하라'와 '더 낫다'는 뭐 문체의 차이겠구요.
그 주장에서는 over가 favor A over B에 속하는 것이 아니라 object composition과 class inheritance를 연결하는 것으로 봅니다. 즉 '클래스 상속에 기반한 객체 합성'으로 해석을 하는 것이지요. Favor object composition on class inheritance으로 보는 것입니다. 그리고 한국어판의 문구가 심각한 오역이 아닌가 하는 문제를 제기합니다.
일단 간단하고 직접적인 문제부터 말하자면.... 만일 그 주장이 맞다면 잘못은 원서의 저자에게 있다고 봅니다. 글을 애매하게 쓴 것이지요. over는 '위에' 보다는 '넘어서', '너머'의 의미가 더 강하다고 알고 있습니다. 게다가 favor A over B라는 관용구가 있으니 오해를 사기에 알맞죠.
그러나 이처럼 많이 인쇄된(제가 가지고 있는 원서는 22nd printing이라고 되어 있네요) 책에서 이 문구가 여전히 남아 있다면 저자의 잘못으로 보기는 힘들지 않을까요. 물론 이것이 본질적인 사항은 아닙니다만....
본격적으로 이야기해보죠. 그 주장의 주된 논지는, 상속과 합성이 각자 장단점이 있고, 각자의 단점을 극복하고 장점을 취하기 위해 클래스 상속과 객체 합성을 결합해서 사용해야 하며, 따라서 저자가 말한 원칙은 상속과 합성 중 하나를 더 선호하라는 것이 아니라 그 둘을 결합한 '클래스 상속에 기반한 객체 합성을 선호하라'는 것이다... 라는 것입니다.
그럼 여기서, 제가 이 부분(원서 18~20쪽)을 어떻게 읽었는지 요약하겠습니다.(깁니다.) 그러면 자연히 그 주장에 대한 제 생각이 드러날 것입니다.
Favor OC over CI라는 원칙은 18쪽 하단에서 시작하는 Inheritance versus Composition이라는 제목의 소단원에 나오는 것입니다. 이 단원 제목도 의미가 있습니다만 넘어가구요.
소단원의 첫 번째 문단은 객체지향 시스템에서 기능성의 재사용에 흔히 쓰이는 기법으로 클래스 상속과 함께 객체 합성이 있다고 소개합니다. 그리고 재사용의 관점에서 본 클래스 상속에 대해 간략히 소개합니다. 두 번째 문단에서는 클래스 상속의 대안인 객체 합성을 간단히 소개합니다. 이 문단의 핵심은 객체 합성이 '블랙박스' 재사용이라는 점이고 블랙박스는 그 전에 나온 첫 번째 원칙 'Program to an interface, not an implementation.'과 관련이 큽니다.
세 번째 문단에서는 상속과 합성에 각자 장단점이 있다고 하면서 클래스 상속의 장점을 이야기합니다. 그리고 네 번째 문단에서는 클래스 상속의 단점 두 가지를 말하는 데 요약하자면 구현 의존성의 증가와 캡슐화 위반입니다.
Implemetation dependencies can cause..로 시작하는 다섯 번째 문단에서는 이 구현 의존성의 문제점을 좀 더 이야기합니다. 구현 의존성은 유연함을 제한하며 따라서 재사용을 제한한다는 것이 핵심입니다.
그 다음 문단은 객체 합성의 장점을 이야기하는데 중요한 것은 객체 합성의 장점이 클래스 상속의 중요한 단점인 구현 의존성 증가를 해소할 수 있다는 것입니다.
그 다음 문단, 즉 19쪽의 마지막 문단에서는 클래스 상속에 비한 객체 합성의 또 다른 장점을 이야기합니다. 핵심은 'helps you keep each class encapsulated and focuesd on one task'입니다. 즉 캡슐화를 언급하고 있습니다. On the other hand...로 시작하는 이 문단의 후반부는 서로 다른 해석의 여지가 있는데요. 이 부분 때문에 '클래스 합성과 객체 조합이 각자 장단점이 있으니 그 둘 모두를 취한다는 의미에서 over는 on으로 해석해야 한다'는 이야기가 나올 수도 있겠습니다. 그러나 제가 보기에 이 부분이 있다고 해도 지금까지의 주된 흐름은 클래스 상속의 중요한 단점들을 객체 합성이 해결한다..입니다.
20쪽으로 넘어와서 저자는 지금까지의 논의를 요약한 하나의 원칙을 제시합니다. 바로 Favor object composition over class inheritance. 입니다. 제가 지금까지 읽은 흐름으로 봤을 때 여기의 over를 일반적인 favor A over B의 over로 이해하지 않을 이유가 없는 것 같습니다.
그 문구 다음의 문단도 여러 가지 해석의 여지가 있겠습니다. 서두에서 말한 그 주장에서는 이 부분을 '이상적으로 조합만을 이용할 수 있는 경우는 극히 드물다. 그러므로 상속을 기반으로한 조합을 하라'고 이해합니다. 그러나 그렇게 해석하는 것은 좀 과하지 않나 싶습니다. 제가 보기에 이 문단의 핵심은, 상속보다 합성을 선호하라는 원칙을 상속을 완전히 배제하라는 뜻으로까지 확대해석하면 안 된다, 그런 것은 현실적으로 불가능하거나 바람직하지 않다, 상속과 합성을 함께 쓰는 것은 자연스러운 일이다 정도입니다.
잠깐 저의 해석을 좀 더 추가하면, favor A over B는 A와 B가 동등한 기능을 하는 경우에, 즉 선택의 여지가 있는 상황에 적용되는 것일 뿐이고 상속과 합성을 함께 써야 한다는 것이 '상속보다는 합성을 선호'한다는 것과 모순되지는 않는다고 생각합니다. 즉 이 문단이 over를 다르게 해석할만한 근거가 되지는 않습니다.
이 문단이 over를 다르게 해석할만한 근거가 되지 않는다는 점은 그 다음 문단이자 이 소단원의 마지막 문단에서 더 잘 나타나는데요. 이 소단원의 결론 격에 해당하는 중요한 문단이므로 전문을 인용하자면:
Nevertheless, our experience is that designers overuse inheritance as a reuse technique and designs are often made more reusable (and simpler) by depending more on object composition. You'll see object composition applied again again in the design patterns.
이 문단을 인용하고 보니 이렇게 길게 이야기할 필요가 없었다는 생각도 드는데요. 어쨌든 저자는 자신들의 경험으로 볼 때 설계자들은 재사용 기법으로서의 상속을 남용하며, 설계는 객체 합성에 좀 더 의존해서 만들 때 더욱 재사용할 수(reusable) 있다(그리고 더 간단하다)고 합니다. 그리고 객체 합성은 설계 패턴들에서 계속해서 적용된다고 말합니다.
결론적으로 저자가 이야기하고자 한 것은 한국어판의 역자가 옮긴 문장과 크게 다르지 않다고 봅니다. 물론 개인적으로는 '더 낫다'보다는 좀 어색하긴 하지만 직접적인 '선호하라'라는 표현이 더 좋습니다.
나머지 자잘한 이야기들....
[#M_ more.. | less.. |
그 주장의 한가지 논거로 책에 나오는 패턴들을 보면 실제로 상속과 합성이 함께 쓰이고 있다는 점이 있는데요. 이 역시 흥미로운 주제입니다. 사실 합성을 위해서는 합성할 객체들이 있어야 하고 그 객체들을 만들어 내는 현실적으로 유용한 방법이 상속입니다(게다가 동적인 다형성을 위한 방법으로 상속이 유일한 언어들도 있습니다). 이것을 '클래스 상속에 기반한 객체 합성'이라고 표현하는 것은 가능한 일이고 흥미로운 주제라고 생각합니다. 다만 그렇다고 over를 다르게 해석할 필요가 있는 것 같지는 않습니다.
좀 더 사족을 달면... 책에 나오는 패턴들이 상속과 합성을 함께 사용하는 것은 그럴 필요가 있기 때문일 것입니다. 즉 상속으로 해야 할 일을 상속으로 하고 있는 것이지 않을까요. 이것이 명확해지려면 책에 나오는 패턴(의 예제 구현)들 중에서 상속으로도 할 수 있고 합성으로도 할 수 있는 부분에서 합성을 택한 것이 몇 개이고 어떤 것들인지를 조사해야 하겠지만, 이부분은 저자들이 자주 써먹는 '독자의 숙제'로 남기겠습니다:) (지금 이 책을 공부하고 계시며 제 생각이 그럴듯하다고 생각하시는 분이 한 번 연구해 주시길~)
사족 더 달기...(지네가 되겠습니다). 다른 책들이나 문장들에서도 흥미로운 언급을 찾을 수 있습니다.
예를 들어 Alexandrescu, Sutter의 C++ Coding Standards는 이 원칙을 "Prefer composition to inheritance."라고 표현합니다. 이 경우는 to를 on으로 해석하기는 힘들겠죠. 그리고 아마존의 GoF Design Patterns 페이지의 Editorial Review에는 The book provides numerous examples where using composition rather than inheritance can improve the reusability and flexibility of code.라는 문구도 있습니다. 만일 저나 역자분의 생각이 틀렸다면 이들 역시 책을 잘못 읽은 것이겠지요... _M#]
예전 댓글(읽기 전용)
-
jeddli, 2006-01-05 11:01 :
-
류광, 2006-01-05 16:01 :
독자가 선호가 아니라 대체를 떠올리게 되는 것이 주장의 핵심은 아닌 것 같습니다. 그런 것은 이미 '섞어써야 한다'라는 결론을 미리 가지고 있는 상태에서 '더 낫다'를 보았기 때문이 생기는 결과가 아닐까요....
결국 저자가 강조한 것이 섞어 써라인가 아닌가의 문제인데요. 원서로 봐서는 아닌 것 같습니다. 단, 저는 한국어판은 보지 못했습니다. 서평에서 문제 삼고 있는 것은 그 문구라서 그 부분을 원서를 가지고 살펴본 것이구요. 역자분이 원서 19쪽 내용 전체를(그리고 20쪽의 단원 마지막 문단까지도) 아예 이상하게 번역했을 수도 있겠습니다. 어떤가요?
-
손영수, 2006-01-05 19:01 :
안녕하세요 손영수입니다. debate를 종식 시킬만한 글이 있습니다. gof의 저자 erich gamma가 직접 이 부분에 대해서 논의한 글입니다.
약간 애매한 결론이 나 버렸네요 ^^ 한번 읽어 보시길 바랍니다. ^^ http://www.artima.com/lejava/articles/designprinciplesP.html
감사합니다. ^^ 좋은 하루 되세요 ^^
-
류광, 2006-01-05 23:01 :
아 와주셨네요~ 고맙습니다.
over의 해석 문제는 해결이 된 셈이네요... 제가 보기에 (적어도 제가 관심을 가졌던 부분에 한해서는) 애매한 결론은 아닌 것 같습니다. 합성을 상속과 함께 쓴다는 것은 원서에서도 했던 이야기니까요.
번역가의 입장에서 한 가지 생각해볼만한 남은 문제는... favor A over B를 좀 더 매끄러운 'B가 A보다 낫다'로 표현하는 것과 매끄럽지는 않지만 오해의 여지가 적은 'B보다 A를 선호하라' 사이의 선택 문제(과연 의미 상의 현저한 차이가 있는가까지도)인데요... 뭔가 쓸만한 생각이 떠오르면 또 글을 쓰겠습니다.
-
손영수, 2006-01-06 03:01 :
안녕하세요 손영수 입니다.
저의 misconcept으로 인해 이렇게 된것 같습니다. 이대로 공부를 해야 될지 --; 위 번역은 아주 정확한 번역입니다. 단지 예전에 앴던 객체 합성을 객체 조합으로만 바꾼 다면요... 저의 무지에서 발생된 글이니 ^^ 이해해 주시기 바랍니다
상속보다는 조합을 선호하라고 했는데. 조합할대는 상속을 쓰라고? 뭔가 뉘앙스가 이상하지 않나요?
class inheritance가 gof에서는 implementation inheirtace를 대변하는 말이였습니다.
바로 상속의 두가지 종류에 대해서 명확한 구분이 필요했던것 같습니다.
그러니 원서에서 서로의 장단점을 논하고 실제 패턴의 구조는 inteface 상속을 기반으로한 composition을 다 취하고 있었던 것입닏.
결론은 구현 상속을 하지 마라는 것이지요 . 인터페이스 상속은 좋은 도구라는 애기입니다.
자세한 글은 아래를 참고해 주세요..
http://www.devpia.com/Forum/BoardView.aspx?no=958&ref=958&page=1&forumname=and_free&stype=
-
류광, 2006-01-07 21:01 :
글 읽어 보았습니다.
제 경우는... 사실 그 부분 전체는 기능성의 재사용에 대한 것이고, 기능성의 재사용은 구현의 재사용에 더 가깝다고 이해했습니다. 인터페이스 상속은 굳이 말을 지어내자면 설계 결정사항의 재사용? 구조의 재사용? 정도이겠구요. 어쨌든 이 부분은 19쪽 중간에서 구현 의존성이 유연성을 해치는 문제의 한 가지 해결책으로 '... inherit only from abstract classes.. '라고 언급한 것과도 관련이 있을 것입니다.
또한 거기서 말하는 합성은 합성의 구성 요소들이 동적 다형성을 가진다는 가정을 깔고 있는데, 책의 예제에 많이 쓰이는 언어인 C++에서 동적 다형성을 위해서는 상속 외의 다른 길이 없습니다. 이 경우의 상속은 적어도 리스코프 대체 원칙에 근거한, 간단히 말하면 가상 함수를 수반한 클래스 상속이겠고 이를 순수 가상 함수로까지 연장한다면 인터페이스 상속과 거의 흡사해 지겠죠.(꿈보다 해몽이 좋습니다^^)
말이 길어졌는데 간단히 요약하자면, 저는 저자가 구현 상속/인터페이스 상속이라고 구체적으로 구분하지 않긴 했지만(inherited implementaion이라는 언급이 나오긴 해도) 문맥으로 볼 때 암묵적으로 그런 구분이 문장들에 녹아 있는 것으로 읽었습니다.
사실 역자나 저자에게 가장 어려운 부분이 이런 부분일 것입니다. 즉 글쓴이가 가정하고 있는 것과 독자가 가정하고 있는 것이 딱 맞아떨어지느냐 의 문제인데요. 제 경우는 다행히 많이 맞아 떨어졌던 것 같습니다. ^^
아 전에 이 내용으로 그 서평을 다신분이 의견을 제시하셔서 토론을 한적이 있었는데 대략적인 주 핵심은 "그렇게 번역이 됨으로써 "선호"가 아니라 "대체"를 떠올리게 된다" 였던것 같습니다. 개발들이 그 번역서를 보며 그렇게 받아 들이게 되니, 번역이 좀 잘못되었다는 애기였죠( 제가 보기에도 좀 그렇습니다. 그냥 책을 읽어 가는 사람으로선 그렇게 받아 들이기 좋게 되어 있죠 ) . 결론이나 주장의 핵심은 모두 같은 애기였지만 그 번역문의 내용이 실제 개발자들에게 "선호"가 아닌 "대체"를 실제로 떠올리게 한다는게 문제였지 싶습니다( 실제로 그분의 주장은 "그러니 당연히 해결책은 섞어서 사용하는 것이 맞겠지요?" 이니깐요 ). 중요한건 실제 그말이 어떻게 번역이 되었느냐가 아니라 실제로 좀 이상한 의미로 전달이 된다 라는것 같습니다.