합성 vs 상속

박정호·2023년 2월 11일
0

Development

목록 보기
3/3
post-thumbnail

🚀 Start

프로그래밍을 할 때 가장 신경 써야할 것 중 하나가 코드 중복을 제거하고 재사용하여 변경,확장을 용이하게 만드는 것이다.

그리고 코드 재사용 기법으로 제일 널리 사용되는 것이 상속합성이다.



⭐️ 상속

상속이란 객체 지향 4가지의 특징 중하나로 클래스 기반의 프로그래밍에서의 개념이다.

💡 4가지 : 추상화, 상속, 다형성, 캡슐화

클래스 상속을 통해 자식 클래스는 부모 클래스의 자원을 물려받게 되며, 부모 클래스와 다른 부분만 추가하거나 재정의함으로써 기존 코드를 쉽게 확장 가능하다.

단, 상속은 그저 코드 재사용을 위한 기법이 아니다. 일반적인 클래스가 이미 구현이 되어 있는 상태에서 그보다 더 구체적인 클래스를 구현하기 위해 사용되는 기법이며, 그로 인해 상위 클래스의 코드를 하위 클래스가 재사용할 수 있는 것 뿐이다.



⭐️ 합성

합성은 기존 클래스를 상속을 통한 확장하는 대신에, 필드로 클래스의 인스턴스를 참조하게 만드는 설계이다.

예를 들어 서로 관련없는 이질적인 클래스 관계에서, 한 클래스가 다른 클래스의 기능을 사용하여 구현해야한다면 합성의 방식을 사용한다고 보면 된다.



🧐 상속 보단 합성

결론부터 말하자면 현업에서는 가능하면 extends를 지양하는 편이다. 즉, 상속에 대한 단점들이 존재하고 합성을 사용하라는 뜻이기도 하다.

객체지향 프로그래밍에서는 결합도는 낮을수록, 응집도는 높을 수록 좋다. 하지만, 상속을 하게 되면 부모클래스와 자식클래스의 관계가 컴파일 시점에 관계가 결정되어 결합도가 당연히 높이지 수 밖에 없다.

그리고 컴파일 시점에 결정되는 관계는 유연성을 상당히 떨이트리며, 실행 시점에 객체의 종류를 변경하는 것이 불간으하여 유기적인 다형성 및 객체지향 기술을 사용할 수 밖에 없다.

이외에도 상속은 부모 클래스에 메서드 추가시 자식 클래스에는 적합하지 않은 메서드가 상속되는 문제, 부모 클래스의 결함이 그대로 넘어오는 문제, 부모 클래스를 변경할 때 자식 클래스도 함께 변경되야하는 동시성 문제 등이 존재한다.

반면, 합성은 구현에 의존하지 않는 점에서 상속과 다르다.왜냐하면 합성을 이용하면 객체의 내부는 공개되지 않고 인터페이스를 통해 코드를 재사용하기 때문에, 구현에 대한 의존성을 인터페이스에 대한 의존성을 변경하여 결합도를 낮출 수 있기 때문이다.



✚ 합성 in React

React에서는 강력한 합성 모델을 가지고 있으며 상속으로 코드를 재사용하기보다는 합성을 이용하여 컴포넌트 간에 코드를 재사용하는 것을 권장한다.


컴포넌트에서 다른 컴포넌트를 담기

어떤 컴포넌트들은 어떤 자식 엘리먼트가 들어올 지 미리 예상할 수 없는 경우가 있는데, 이러 한 컴포넌트에서는 특수한 children prop을 사용하여 자식 엘리먼트를 출력에 그대로 전달하는 것이 좋다.

function FancyBorder(props) {
  return (
    <div className={'FancyBorder FancyBorder-' + props.color}>
      {props.children}
    </div>
  );
}

function WelcomeDialog() {
  return (
    <FancyBorder color="blue"> // children에 들어갈 내용
      <h1 className="Dialog-title">
        Welcome
      </h1>
      <p className="Dialog-message">
        Thank you for visiting our spacecraft!
      </p>
    </FancyBorder>
  );
}

여러 컴포넌트 전달하기

props.children 으로 단 하나의 자식 Element 를 전달할 수 있겠지만, 종종 여러 개의 Element 들을 전달해야 할 경우가 있다. 이런 경우에는 children 대신에 고유한 방식을 적용할 수 있다.

  • <Contacts /><Chat />같은 React 엘리먼트는 단지 객체이기 때문에 다른 데이터처럼 prop으로 전달할 수 있다.
function SplitPane(props) {
  return (
    <div className="SplitPane">
      <div className="SplitPane-left">
        {props.left}
      </div>
      <div className="SplitPane-right">
        {props.right}
      </div>
    </div>
  );
}

function App() {
  return (
    <SplitPane
      left={
        <Contacts />
      }
      right={
        <Chat />
      } />
  );
}

끝으로, React에서는 상속 계층 구조로 작성할만한 사례는 딱히 없다. props와 합성은 명시적이고 안전한 방법으로 컴포넌트의 모양과 동작을 커스터마이징 하는데 필요한 모든 유연성을 제공한다.

그리고, 만약 UI가 아닌 기능을 여러 컴포넌트에 재사용하고 싶다면, 상속받을 것이 아니라 별도의 JS 모듈로 분리하여 컴포넌트에서 import하여 사용면 그만이당!


🔗 Reference
👉 [OOP] 💠 상속을 자제하고 합성(Composition)을 이용하자
👉 합성 (Composition) vs 상속 (Inheritance) - React 공식문서

profile
기록하여 기억하고, 계획하여 실천하자. will be a FE developer (HOME버튼을 클릭하여 Notion으로 놀러오세요!)

0개의 댓글