Pattern이라는 분야에서 GoF의 Design Patterns가 가지는 의미는 굳이 말을 하지 않아도 될듯 합니다.

몇몇 지식 계층들을 위한 학회에서나 애기되어지고 있는 Pattern들을 일반인들에게 알리는 신호탄 같은 존재이기 때문입니다.

예전 블로그에 올린 글이지만, 패턴을 공부하시거나 접하시는 분에게는 꼭 필요한 내용이라  재 포스팅 합니다.

이 포스트를 통해서 Design Pattern의 두번째 원칙에 대한 오해들을 여러분과 공유하고자 합니다.

문제가 되는 두번째 원칙을 보도록 하죠.  🙂

Favor Object Composition over Class Inheritance

이 말의 의미는 원문 그대로 해석을 한다면 클래스 상속보다는 객체 조합을 선호해라 라는 애기입니다.  대부분의 시중에 나와 있는 책들이 상속보다는 조합을 선호하는 것으로 의미를 파악하고 전달하고 있습니다.

물론 그 당시 CBD가 널리 유행했던 것도 한 몫했죠 🙂   과연 이말이 맞는걸까요?

6년 동안 다양한 패턴에책들을 본 경험을 들어 볼때, 상속이라는 것은 모든 패턴에 사용되고 있었습니다.

거기다 graybox 즉 whitebox(상속)과 blackbox(조합)을 함께 적용하는 것이 패턴계의 철학으로 굳혀져 있어서 과연 이말이 맞는지 많은 의구심을 가지게 되었습니다.

디자인 패턴의 첫번째 원칙인 Program to an interface, not to an implementation 에서도, Program은 인터페이스 지향적으로 짜야 된다는 의미가 나와 있고, 이것은 곧 상속을 의미하는데 왜 상속보다 구현을 선호하라고 했을까? 라며 혼자 계속 반문했습니다.

지금 한번 여러분이 가진 패턴책을 펴보시길 바랍니다.  어느 패턴이라도 인터페이스 상속을 받지 않은 패턴을 찾기 힘들 정도 인데, 과연 상속 보다 조합을 선호하는 이분법적인 사고가 맞는 걸까?

필자는 서 짧은 영어 실력으로 Favor Object Compoistion over Class Inheritance를 클래스 상속을 기반으로한 객체 조합을 선호해라 라는 의미로 해석을 시도했습니다.  아마 graybox의 철학을 보아도 맞다는 자신감이 있었기 때문이지요 🙂

상당히 그럴싸 하지 않은가요?  물론 저의 영어 실력이 그리 뛰어난 편은 아니지만, 왠지 상속을 기반으로 한 조합 이라는 의미를 부여했을때, 좀더 GoF Design Pattern에 맞게 해석된것 같아 나름 뿌듯했습니다.

그런데 이게 왠일인가요?  그런데 컴퓨터 분야에 유명한 번역가이신 분에게 반론이 들어왔습니다.

Favor Object Composition over Class Inhertance는  클래스 상속보다는 객체 조합을 선호해라 라는 의미가 맞다고.  그분이 워낙 컴퓨터 영역에서는 전문가 이시라. 여러가지 예를 들며 온라인 상으로 애기를 나누게 되었습니다.

대학원에서 분산 객체와 패턴을 전공으로 하고, 스터디를 몇년동안 해왔는데.. 과연 저말이 맞는 걸까? 상속보다 객체 조합이 훨씬 나은 거라고 말할수 있는 걸까?

왜냐면 객체지향 초기에 가장중요시 여기는 개념은 재사용성(Reusability) 이었지만, 지금은 워낙 시스템이 방대해지고 잦은 변화가 발생하다보니 유연성(Flexiblity)이 더 중요한 개념으로 여겨지고 있기 때문입니다.

유연성을 가장 쉽게 확보하는 방법이 상속을 통해서 다양한 Concrete Class를 만드는 방법인데.  객체 지향에 과연 저 말이 맞는 의미인가 반문하며 많은 생각을 했습니다.

그런데 구글링을 하다가 이러한 의문점을 해소해 주는 GoF 패턴의 저자인 Erich Gamma의 인터뷰 내용을  발견했습니다.

http://www.artima.com/lejava/articles/designprinciplesP.html

이 인터뷰를 통해서 깔끔한 정리를 할수 있었습니다.

두번재 원칙인 Favor Object Composition over Class Inhertance 에서 Object Composition은” 상속을 사용하지 말라는 의미가 아니다”라는 것이었습니다.

A common misunderstanding is that composition doesn’t use inheritance at all.

Composition is using inheritance, but typically you just implement a small interface and you do not inherit from a big class

Object Composition은 내부적으로 Interface Inheritance를 사용하다는 말이 명시적으로 있었습니다.

필자가 저런말을 하니 뭔가 다시 한번 Design Pattern 책을 살펴보았습니다.

두번째 원책 몇페이지앞에서 재미난 말을 발견했습니다.

P. 17 세번째 단락. (GoF Design Pattern 원서..)

Class inheritance defines an object’s implementation in terms of another object’s implementation

In short, it’s a mechanism for code and representation sharing..

두번째 원칙의 Class Inheritance는 Implementation Inheritance 였던 것이다.

아마 이 두번째 원칙의 잘못된 오해 때문에, 조합이 좋다라고 단언하는 책이나 사람들이 있습니다.

국내 서적에서 상속보다 조합이 더 낫다라고 해석한 몇분의 지식 오류로 인해.. Composition한 부분만 너무 강조 된것이 아닌가 하고 걱정되어 지기도 합니다.

그럼 두번째 원칙을 다음과 같이 명확히 말하면..

Favor Object Composition (with Interface Inheritance) over Implementation Inheritance.

Favor Object Composition (withSubtyping) over Subclassing.

구현 상속 보다는 (인터페이스 상속을 기반으로한 ) 객체 조합을 선호하라는 말로 해석되어 질수 있습니다. 객체의 세계에서는 상속과 조합의 아름다운 결합을 추구하는 것이 패턴의 아름다운 진리이죠.

이 글로 인해 많은 분이 Design Pattern의 두번재 원칙을 파악하는데 도움이 되길 바라며 글을 마무리합니다.

Join the conversation! 18 Comments

  1. 2007년 데브데이 키노트때 기초와 기본에 대해서 이야기하고 기본으로 돌아가라는 NTO 박명호 박사님의 이야기가 생각이 납니다. 이글을 다시 읽으면서 기본을 다시한번 볼아보게 됩니다. 기본이라는것은 돌아보고 돌아보고.. 몇번이고 곰씹을 필요가 있는듯합니다. 이전 포스트글을 읽었었는데 다시 읽으니 또 새롭네요..

    답글
  2. 신사웅 >>
    안녕하세요 신사웅 시삽님.
    기본으로 돌아간다는 것이 참 힘든것 같습니다.

    경력이 많고 실력도 대단하심에도 불구하고, 항상 다른 분의 강의나 의견을 경청해 주시는 자세를 보고 많이 배웠습니다.

    전 이제부터 이러한 기본을 갖추며 살려구요.
    여튼 방문해 주셔서 감사하시구요.

    WCF 세미나에 대해서 어떻게 생각하시는지요?
    말을 드려도 답변이 없으시기에 ㅎㅎㅎ

    답글
  3. […] leave a comment » 잘못 알려진 디자인 패턴의 두번째 원칙 « arload – load to architect […]

    답글
  4. 저 말에서의 이슈는 다형성의 관점보다는 중복 코드를 제거하는 방법의 관점인 것 같습니다. 상속이나 조합이나 둘다 중복 코드를 제거하는 방법입니다. 상위클래스로 빼면 상속인 거고, 외부 클래스로 빼서 import해서 쓰면 조합입니다. 이 둘 중에 선택해야 할 때 조합이 더 straightforward한 방법이니 조합을 쓰라는 것이지요.

    인터페이스는 상속보다는 다형성의 관점입니다. 실상, “인터페이스 상속”에서 중요한 것은 “상속”이 아니고 “인터페이스”죠. 그래서, 패턴에서 상속을 많이 쓰고 있지만 실제로는 상속의 장점을 취하는 것이 아니라 인터페이스의 장점을 취하고 있습니다. 사실 용어도 인터페이스 상속이라는 말은 잘 안 나오죠. 인터페이스를 구현implement한다고 하는 경우가 많습니다.

    그래서, 일반적으로 상속 대신 조합을 쓰라는 말은 그대로 받아들여도 좋을 듯 합니다. 역자 분이 이런 점을 생각하고 그렇게 번역하셨는지는 모르겠으나, 결과적으로 괜찮은 번역이었다는 생각입니다.

    답글
  5. 영록님>>

    안녕하세요 영록님.
    좋은 말씀 감사합니다.

    예전에 이글을 적었을대 역시 동일한 질문이 저희 스터디 팀 내부적으로 나왔습니다. 🙂

    이 책이 나온 시점이 Java가 나오기 전입니다.
    interface 를 implement 한다는 말은 java에서 표현하는 방식이죠

    그렇기 때문에 Interface를 Implement 한다라는 말은 시대적으로 오류가 있는 말입니다.

    그렇게 때문에 interface 만 상속받는 subtyping 과 실제 구현 class 를 상속받는 subclassing을 구분한느 관점이 더 명확합니다.

    그리고 단순히 상속을 통해 얻는 인터페이스 관점 보다는 template method 와 같은 일괄적인 제어흐름을 지정하는 방법이 사실상 더 많이 이용됩니다.

    이러한 부분도 있기 때문에, 충분히 오해의 소지가 발생될 수도 있습니다. 이러한 오해를 패턴을 처음 배우는 분들이 가지지 않기 위해 글을 쓴것입니다.

    상속 대신 조합을 쓰라는 말로 많은 분들이 misconception을 가진다면. 이건 충분히 고쳐야 되는 말이지요 🙂

    답글
  6. 인터페이스를 구현한다는 말은 스몰토크 시대에도 많이 썼던 말입니다. 자바의 interface란 키워드가 어디서 나왔겠습니까. 하늘에서 뚝 떨어진 것이 아닌 이상 기존 프랙티스에서 가져와야 하는 것이지요. 자바는 Objective C를 모태로 하고 있고 Objective C는 스몰토크의 영향을 많이 받았습니다. 스몰토크에는 interface가 키워드로 존재하지 않지만 개발자들은 개념적으로 interface를 활용했고 그 개념을 이어 받기 위해 interface를 만든 것입니다. 왜 C++처럼 abstract만 있어도 되는데 굳이 개념의 단순화를 지향하던 자바가 새로운 키워드까지 써가면서 interface 개념을 도입했겠습니까.

    template method. 이 패턴의 가치는 다형성에 있는 것입니다. 그런 면에서 template method 역시 상속보다는 인터페이스에 방점이 찍혀 있는 패턴이라고 봐야 할 것입니다.

    어쨋거나 결론은 비슷할지도 모릅니다. 구현 상속은 나쁘다는 것이죠. 비록, 저 말이 상속 전체를 나쁜 것으로 몰아갈 오해를 불러일으킬 수도 있겠지만, 패턴 책을 읽다보면 자연스럽게 “아, 구현 상속이 나쁜 거구나”하는 결론에 도달할 수 있을 것이라고 봅니다. 그런 면에서 딱히 저 번역이 잘못된 것이 아니라고 보는 것입니다.

    사실 더 나아가, 인터페이스 상속도 의미를 잃어가고 있습니다. duck typing으로 인해 인터페이스 상속이란 게 필요 없어졌죠. 물론, 개발자의 머리 속에서의 인터페이스 상속은 여전히 필요합니다만, 문법적 요소로서의 상속은 없어져도 될만한 상황이 되었습니다.

    물론, 당시에는 duck typing까지 고려하고 저 말을 쓰지는 않았겠지만, 오히려 현대적으로 해석할 때 저 말이 더 의미 있게 다가올 수 있을 것 같습니다. 그런 면에서 저는 여전히 저 번역을 지지합니다.

    이 문제에 대해서는 기존의 OOP 커뮤니티 사이에서도 많은 논란이 있었습니다. 패턴의 진원지 c2.com에서 찾아보시면 재미 있는 토론을 많이 보실 수 있을 것입니다.

    답글
  7. 🙂 좋은 말씀 감사합니다.

    역시 동감합니다. 아마 비슷한 결론이지만 가장 큰 차이는 이겁니다.
    과연 디자인 패턴을 처음 접하는 사람들 대부분이 GoF 패턴을 다루는데, 객체 지향적인 생각없이 자연스럽게 구현 상속이 나쁜거구나를 깨우치는데 시간이 얼마나 걸리까요?

    제가 올린 인터뷰 내용에서 처럼 왜 많은 사람들이 상속은 나쁜 것이라고 misconception을 일으킬까요?

    지식은 나눌때 힘이되고, 바로 잡을때 힘이 되는 것입니다. 누군가 지식을 먼저 아는 사람 입장에서, 그걸 쉽게 풀어주고 잡아 주는 것이 과연 의미가 없는 것일까요?
    책이라는 것은 모르는 지식을 쉽게 알려주는 것이 목적입니다. misconception을 일반 독자들이 느끼고, 더구다나 많은 논란까지 있었다면, 그건 지식 전달을 실수한 것이지요.
    그리고 책에서 객체지향의 두 원칙으로 내세웠을 만큼 중요한 문장이라면, 더 명확하게 적는것이 낫지 않을까요?

    그리고 저같이 smalltalk에 대한 관심이 없는 사람들이나 C++로 객체를 처음 접한 사람들은, 당연히 개념이 정확히 잡혀 있지 않았을 것입니다.
    저처럼 C++ 로 객체를 접한 사람은, 충분히 misconception을 일으킬만한 내용이죠..
    이런 관점에서 봐 주시기 바랍니다.

    template method 패턴이 다형성을 지원하는건 당연합니다. gof 패턴뿐만 아니라 모든 패턴들이 대부분 다형성을 포함하고 있는 것은 사실입니다.
    하지만, template method를 통해서 일원화된 흐름제어라는 것이 더 큰 묘이지요. 다형성은 대부분의 패턴이 가지는 특징입니다.
    뭐 이것 역시 객체를 대하고, 다루는 경험이 달라서 그럴 것이라 예상이 됩니다. 🙂

    결론은 지식은 나눌때 더 큰힘이 된다고 생각이 들고, 다른 분이 오해에 소지가 없게 나누었을 뿐입니다…
    명확한 지식 전달의 관점에서 이해해 주시길 바랍니다.. 🙂 감사합니다.

    답글
  8. 좋은 글 잘 읽었습니다. 🙂

    예전에 챗하면서 잠깐 언급해주셨는데, 정확하게 이해하지 못하고 있었습니다.

    잘 정리하여 주셔서 이제 점 많이 이해가 옵니다.

    그리고 저도 영문을 한글로 옮기는게 생각보다 많이 어렵습니다. 저자의 의도를 명확하게 파악하기가 참 어렵기 때문입니다.

    그래서 여러모로 고증이 필요한듯 합니다.

    제가 패턴은 잘 모르지만 좋은 고증인것 같습니다.

    앞으로도 좋은 글 부탁드립니다.

    감사합니다. 😉

    답글
  9. 재미있는 내용입니다. 그런데 한가지 궁금한 것은…

    P. 17 세번째 단락. (GoF Design Pattern 원서..)
    Class inheritance defines an object’s implementation in terms of another object’s implementation

    은 어떻게 번역이 되어 있나요? (번역판을 못봐서 전 모릅니다.) 이부분이 번역이 빠져있다면 모를까 같이 번역되어 있다면 잘못 전달되고 있다고 할 수 있을까요?

    답글
  10. C-Thinker >>
    안녕하세요 손영수입니다.

    저의 글을 제대로 읽어 주시길 바랍니다.
    이글을 통해 국내 번역서를 비판 한적이 없습니다.
    저 역시 책을 번역하는 입장이라, 번역의 고충을 압니다.

    1판에는 번역이 잘못된 부분이 많았지만, 2판에 와서는 많이 수정했습니다.

    다만 많은 책들이나 글들이 위 두번째원칙을 기반으로 계속해서 상속은 나쁘고 조합은 좋다라는 이분법적인 글로 오해를 만들어 버린다는 거죠.

    이러한 오해를 좀더 줄이자는 의미일 뿐입니다.

    아마존의 GoF책에서 언급한 Editional Review를 보면 이러한 문장이 있습니다. The book provides numerous examples where using composition rather than inheritance can improve the reusability and flexibility of code.

    그리고 Alexandrescu, Sutter의 C++ Coding Standards는 이 원칙을 “Prefer composition to inheritance” 라고 말합니다.

    잘못된 개념들을 바로잡아 국내 개발자에게 전달하고 싶었을 뿐입니다.. 따뜻한 관심 감사드립니다. 🙂

    답글
  11. GoF 책 자체의 번역이 아닌 그책을 참고하는 다른 책들을 말씀하시는 것이었군요. 내용이 잘못 전달되고 있다고 몇번을 말씀하셔서 전 그 책의 번역서를 말씀하시는 줄 알았습니다.

    답글
  12. C-Thinker >>
    아 예 이해해 주셔서 감사합니다.
    제가 좀더 명확하게 전달하지 못한 것도 문제인듯 하네요.

    post를 약간 수정해야 겠네요 🙂

    답글
  13. ‘얘기’ 를 설마 ‘애기’로 알고 있는 것은 아니겠쥐??? ㅋ
    뎁퍄- 갔다가 건너건너 들어왔3,
    글 잘 보고 갈께^^~ 좋은 하루!

    답글
    • 오랜만이군요 형..
      오타를 정확히 집어 내시는 군요..

      잘 살고 있죠 🙂 큰 꿈을 이루시고, 꼭 날아가소서!!
      충성~~~

      답글
  14. 와 이렇게 훌륭한 글이 벌써 8년전에 있었네요. 그렇게 디자인 패턴 관련 블로그를 많이 뒤졌는데 이제서야 발견하다니 ㅜㅜ 아깝네요.
    너무 늦은 댓글이지만 좋은 글을 봐서 댓글을 안 달수가 없네요.

    답글
    • 답변이 많이 늦었네요.. 패턴은 선배들의 지식이라고 생각하시고 너무 무겁지 않게 보세요 🙂 홧팅입니다!

      답글
  15. 2달 동안 열시미 정리했습니다.
    객체지향과 패턴에 관심이 많아서 무겁게 보고 있습니다 ㅎㅎㅎ

    “상속보다 구성을 선호해라” “구성이 상속보다 나은 방법이다”라는 원칙을
    정리를 해보니 말 그대로 상속보다 구성이 낫다라는 의미더라구요.
    디자인 패턴관점에서 해석해보면 인터페이스 상속을 통해 확장하는 것보다 구성을 통해 확장하는 것이 더 장점이 많다라는 의도인거죠.
    디자인 패턴관점에서 이 원칙은 구현 상속과 크게 관련이 없더라구요.
    처음에 구현상속이 구현을 상속받는 걸의미하는 줄 알았는데 아니더라구요.

    예를 들어 팩토리 메소드 패턴과 전략패턴은 상속과 구성의 차이이죠.
    두 방법을 비교했을 때 구성을 이용한 전략 패턴이 낫다라는거죠.
    결국 인터페이스를 분리하는 것이 낫다라는 것이죠,

    인터페이스 상속으로 상속으로 확장 했을 때 장점은 쉽교 간편하고 부모클래스의 수정이 용이한죠.

    반면 구성을 이용하면
    구성은 상속을 사용하지 않기 때문에 캡슐화를 유지할 수 있으며 클래스의 계층구조가 복잡해지는 상황을 예방할 수 있습니다.
    그리고 상속을 이용하면 실행시점에 변경할 수 없는 단점이 있지만 구성을 이용하면 실행시점에 변경 가능하도록 할 수 있습니다.
    그리고 인터페이스를 잘 만들어 놓으면 모듈단위로 재사용성을 높일 수 있습니다.
    그리고 인터페이스를 명확히 분리하기 때문에 조금 더 객체지향 설계 원칙에 부합하는 코드를 가능하게 해 줍니다.

    이런 장점들 때문에 구성을 이용하는 것이 훨씬 나은 방법일 수 있다는 것이죠.
    물론 그렇다고 상속을 사용해라라는 의미를 가지는 건 아니라고 생각합니다. 왜냐면 상속의 쉽고 간편한 장점은 구성의 모든 장점을 상쇄할 만큼 아주 강력하니깐요.

    아무튼
    결국은 이 원칙은 궁국적으로 말하고자 하는건 구성을 조금 더 선호해라가 아니고 인터페이스를 분리해야 하는 근거 원칙이 되는게 아닌가 생각합니다.

    답글
    • 안녕하세요. 외로이 독학님. 맞는 말씀입니다.. 흔히 이분법의 논리로 생각을 하는데 그렇게 하지 말고, 둘다를 적절히 섞으면 서로의 단점은 없어지고 강점은 취할수 있다는 것으로 넓게 받아 들이고 있습니다.

      좋은 말씀 감사합니다. 🙂

      답글

“잘못 알려진 디자인 패턴의 두번째 원칙”에 작은 댓글하나 « 철수네 소프트웨어 세상 [본점]님에게 덧글 달기 응답 취소

이 사이트는 스팸을 줄이는 아키스밋을 사용합니다. 댓글이 어떻게 처리되는지 알아보십시오.

카테고리

Articles, Books & Articles, GoF, My Thinking, Pattern, Software Engineering, Study

태그

, , , ,