상속(Inheritance), 합성(composition) 과 리액트

2023. 2. 25. 00:37프론트엔드/ReactJS

날짜: 2023년 2월 24일
태그: 프론트 엔드

  • 개발을 진행하다 보면 중복되는 코드와 빈번히 재사용하는 코드를 볼 수 있다.
  • 중복되는 코드를 분리해서 재사용하면 차후 유지보수에도 도움이 되고, 남이 볼 때 쉽게 코드를 파악할 수 있다.
  • 상속과 합성은 객체지향 프로그래밍에서 널리 사용되는 코드 재사용 기법이다.

상속

상속이란?

  • 상속(Inheritance)은 객체들 간의 관계를 구축하는 방법이다.
  • 이 때 객체를 상속받는 객체 클래스는 자식, 상속된 객체는 부모 클래스이다.
  • 클래스 상속을 통해 자식 클래스는 부모 클래스의 자원을 물려 받게 되며, 부모 클래스와 다른 부분만 추가하거나 재정의 함으로 써 기존 코드를 쉽게 확정 할 수 있다.
class Animal {
// #는 private 접근 제한자
#age;
#name;
//생략하면 public
weight;
}

class Bird extends animal {
/.../
}
  • 상속 관계를 is - a 관계 라고 한다.
  • 부모클래에서 접근자에 따라 자식클래스에 접근권한이 바뀜
    • public → 외부에서 접근 가능
      • public의 접근 권한은 외부에서 사용가능 하므로 이미 구현이 완료됐다는 의미이다.
    • protected → 자식클래스에서만 접근 가능
      • protected의 접근 권한은 아직 부모클래스에서의 행동을 미구현 했다는 의미와 변경 가능성을 열어두는 것이다.
    • private → 둘다 접근 불 가능

상속은 언제 사용하는가?

  • SOLID 법칙중 …→ 하위 타입은 상위 타입에서 정의한 명세를 벗어나지 않는 범위에 구현해야한다.
  • Liskov Subsustitution Principle : 상속받은 자식 클래스는 부모 클래스를 대체 할 수 있는 경우에만 상속을 해야함.

상속의 장점

  • 외부로부터 다형성을 보장합니다.
  • 공통된 로직을 재사용할 수 있습니다.
  • 변경되는 로직을 일부 구현하면 사용가능 합니다.

잘못된 상속

  • 코드를 재사용하기 위해 상속을 사용하는것은 잘못됐다.
  • 캡술화를 위반할 수 있기 때문이다.
  • 객체간 설계가 결합 되기 때문에 설계가 유연하지 않다.
  • 하나의 기능을 추가하거나 수정하기 위해 불필요하게 많은수의 클래스를 추가해야 하고, 수정해야 한다.
  • 단일 상속만 지원하는 언어는 오히려 중복코드의 양이 늘어난다.

합성

합성이란?

  • 객체가 다른 객체의 참조자를 얻는 방식 ( has-a )
  • 코드를 재사용하고 싶을 때 사용하면 유리함.
  • 매세지를 통한 느슨한 결합
  • 합성 & 인터페이스 타입을 사용하면 런타임 시 외부에 필요한 전략에 따라 교체하며 사용가능하며 좀 더 유연한 설계가능 → 전략패턴
  • 중복되는 로직들을 갖는 객체를 구현하고, 이 객체를 주입 받아 중복 로직을 호출함으로서 퍼블릭 인터페이스를 재사용하는 방법이다.

단점

  • 객체 관계가 수직관계가 아닌 수평관계가 된다.
  • 많은 부분에 결쳐 합성이 사용될 때 객체나 메소드명이 명확하지 않으면 가독성이 떨어지고 이해하기 어려워짐 → 클래스를 용도에 맞게 분리하고, 인터페이스 설계를 잘해야함

리액트에서의 합성

컴포넌트 기반언어인 리액트에서 컴포넌트끼리 합쳐져야 할 경우가 생김

컴포넌트안에 다른 컴포넌트 담기

어떤 컴포넌트들은 어떤 자식 컴포넌트가 올지 예상이 되지 않는다.

ex) Sidebar/ Dialog/ Modal

retrun <div>
    {props.children}
</div>;

props의 children을 사용해서 자식 element를 그대로 출력에 전달한다.

retrun( 
<div>
    <div>
        {props.left}
    <div>
    <div>
        {props.right}
    <div>
</div>
);

여러개의 element가 올 경우엔 이를 임의로 구분할 수 있을 것이다.

특수화

때로는 어떤 컴포넌트의 특수한 경우를 고려해볼 수 있음.

Dialog → Welcome Dialog 이같은 경우도 “합성”을 통해 해결함

function Dialog(props) {
  return (
    <FancyBorder color="blue">
      <h1 className="Dialog-title">
        {props.title}
      </h1>
      <p className="Dialog-message">
        {props.message}
      </p>
    </FancyBorder>
  );
}

function WelcomeDialog() {
  return (
    <Dialog
      title="Welcome"
      message="Thank you for visiting our spacecraft!" />
  );
}

출처
https://ko.reactjs.org/docs/composition-vs-inheritance.html

https://inpa.tistory.com/entry/OOP-💠-객체-지향의-상속-문제점과-합성Composition-이해하기