[React] SOLID 원칙 기반 클린 코딩 2 - OCP

olwooz·2022년 12월 31일
0

React

목록 보기
4/8

OCP - Open-Closed Principle

한국어로는 개방-폐쇄 원칙이라고 부른다.
객체는 확장에는 열려 있고 변경에는 닫혀 있어야 한다는 원칙이다.
다시 말해 기능이 추가되거나 변경될 때 기존 코드를 변경하지 않아도 되어야 한다는 의미이다.

버튼 컴포넌트를 예시로 들겠다.

// Button.tsx

import {
  HiOutlineArrowNarrowRight,
  HiOutlineArrowNarrowLeft,
} from "react-icons/hi";

interface IButtonProps
  extends React.ButtonHTMLAttributes<HTMLButtonElement> {
  text: string;
  role?: "back" | "forward";
}

export function Button(props: IButtonProps) {
  const { text, role } = props;

  return (
    <button {...props}>
      {text}
      <div>
        {role === "forward" && <HiOutlineArrowNarrowRight />
        {role === "back" && <HiOutlineArrowNarrowLeft />}
      </div>
    </button>
  );
}
// index.tsx

import { Button } from "./button";

export function ButtonsPage() {
  return (
    <div>
      <Button
        text="Go Home"
        role="forward"
      />
      <Button
        text="Go Back"
        role="back"
      />
    </div>
  );
}

Button 컴포넌트는 props를 전달받고, 그 안의 role이라는 property를 기반으로 버튼에 들어가는 아이콘을 결정하고 있다.

만약 새로운 role을 추가해야 하는 상황이 발생한다면
1. IButtonProps에서 role에 새로운 값을 추가하고
2. react-icons/hi로부터 새로운 아이콘을 import하고
3. Button 내부에 조건문과 import한 아이콘을 추가해야 한다.

위 컴포넌트는 OCP를 준수하지 않고 있다.
확장을 위해선 기존 코드의 많은 부분을 변경해야 하기 때문이다.
여러 개의 role이 추가된다면 코드가 쓸데없이 길어지고 복잡해질 것이다.

OCP를 준수한 코드로 개선해보겠다.

// Button.tsx

interface IButtonProps
  extends React.ButtonHTMLAttributes<HTMLButtonElement> {
  text: string;
  icon?: React.ReactNode;
}

export function Button(props: IButtonProps) {
  const { text, icon } = props;

  return (
    <button {...props}>
      {text}
      <div>
        {icon}
      </div>
    </button>
  );
}
// index.tsx

import { Button } from "./button";
import {
  HiOutlineArrowNarrowRight,
  HiOutlineArrowNarrowLeft,
} from "react-icons/hi";

export function ButtonsPage() {
  return (
    <div>
      <Button
        text="Go Home"
        icon={<HiOutlineArrowNarrowRight />}
      />
      <Button
        text="Go Back"
        icon={<HiOutlineArrowNarrowLeft />}
      />
    </div>
  );
}

React 컴포넌트는 props로 전달이 가능하기 때문에, 이런 식으로 role을 없애고 Button을 사용하는 곳에서 icon 컴포넌트를 직접 import해서 props로 전달해주도록 하면 자유롭게 확장이 가능하고 기존의 Button 코드를 변경할 필요도 없다.

세 줄 요약

  1. OCP는 객체가 변경에는 닫혀 있고 확장에는 열려 있어야 한다는 원칙이다.
  2. 컴포넌트의 내부 코드를 직접 수정하지 않아도 기능의 확장이 가능해야 한다.
  3. 조건에 따라 다른 자식 컴포넌트를 렌더링하는 컴포넌트에는 자식 컴포넌트를 props로 전달한다.

참고 자료: https://www.youtube.com/watch?v=MSq_DCRxOxw

0개의 댓글