카테고리 없음

[SOLID 원칙] 프론트엔드의 SOLID 원칙과 과거 프로젝트에 대한 회고 두 번째, 개방 폐쇄 원칙

개형이 2024. 2. 23. 17:29

 

 

지난 포스팅에 이어 SOLID 원칙 관련 포스팅을 보고

 

지난 프로젝트에 대해 회고하는 시간을 가져보고자 한다.

역시나 참고한 포스팅은 아래와 같다.

 

https://fe-developers.kakaoent.com/2023/230330-frontend-solid/

 

 

 


 

 

 

❗️이번에는 개방 폐쇄 원칙에 대해 기술해 볼 것이다.

  • SRP : Single Responsibility Principle (단일 책임 원칙)
  • OCP : Open/Closed Principle (개방 폐쇄 원칙)
  • LSP : Liskov Substitution Principle (리스코브 치환 원칙)
  • ISP : Interface Segregation Principle (인터페이스 분리 원칙)
  • DIP : Dependency Inversion Principle (의존성 역전 원칙)

 

 


 

 

 

1. 개방 폐쇄 원칙 (SOLID의 O) (Open-Closed Principle)

 

개방 폐쇄 원칙은 쉽게 말하면

"요구사항이 변경되더라도 기존 코드의 구조를 수정하면 안 되고 새로운 코드를 추가해야 한다."

 

초기 출시만을 바라보며 급하게 달려온 프로젝트의 내부를 살펴보면

수많은 레거시 코드, 기술 부채가 존재한다.

 

물론 내가 참여한 프로젝트가 그랬다. 😇

 

Annotation을 보면 2~3년전에 작성한 코드가 그대로 있는 부분이 다수 존재했고

작성자는 이미 회사에 없는 경우라

왜 이렇게 작성했어요? 라고 물어볼 수 없는 상황이었다.

물론 그 당시 내가 작성했어도 퇴사했더라면 다른 사람들이 이건 누구야? 라고 욕을 했을 것이다.

 

하지만 어디선가 그런 말을 들은 적이 있고 전적으로 동의한다.

 

"내가 오늘 작성한 코드도 레거시 코드가 된다"

 

그렇기 때문에 레거시 코드를 고칠 때 이 또한 성장이라 생각하고 기쁘게 맞이하려는 마음가짐을 가지며

 

서론을 마치고...

 

 

 

개방 폐쇄 원칙은 컴포넌트를 만들 때 중요한 부분이라고 생각한다.

 

프로젝트를 회상하며 내가 만났던 코드의 일부를 대략적으로 표현해봤다.

 

 

<Table bordered>
   {/* ... */}
   <tbody>
            {
              apiResponse.result.map((obj) => (
                <tr key={obj.id}>
                  <td>{obj.a}</td>
                  <td>{obj.b}</td>
                  <td>{obj.c}</td>
                  {/* ... 줄줄이 나열 ... */}
                </tr>
            }
   <tbody>
</Table>

 

 

위 코드 Table의 각 Row에 Col이 나열되어 있어서

기획 수정으로 인해 Col이 추가되거나 제거 혹은 api의 변경으로 인해 property 이름을 수정해야 하는 경우에

코드 수정이 불가피할 것이다.

 

심지어 저런 코드가 복사되어 다른 페이지에도 사용되고 있어 고치는데 참 난항이었던 기억이 있다.

무분별한 코드 복사는 조심하자!

 

여하튼 위 코드는 개방 폐쇄 원칙에 어울리는 코드는 아니어서

기획이 수정되거나 api가 바뀔 경우에도 코드 수정이 생기지 않도록 바꿀 필요가 있었다.

 

 

// 객체 배열의 첫 번째 요소를 가져와 객체의 키를 추출
const columns = apiResponse.length > 0 ? Object.keys(apiResponse[0]) : [];

return (
<Table bordered>
   {/* ... */}
   <tbody>
            {
              apiResponse.map((obj) => (
                <tr key={obj.id}>
                  {columns.map((column) => (
              		<td key={column}>{obj[column]}</td>
            	  ))}
                </tr>
            }
   <tbody>
</Table>
)

 

 

위와 같이 코드를 수정했을 때

기획이 변경되어 column이 추가되거나 수정될 경우에도

따로 코드의 구조를 수정할 필요가 없게 된다.

 

다만, 위 코드는 단순이 테이블에서 데이터를 나열할 때만 유효하며

테이블 내에 버튼과 같은 다른 기능 추가가 필요할 경우에는

table row 컴포넌트를 따로 만들어 처리하는 작업이 필요할 것 같다.

 

 


 

 

 

 

참고한 포스팅에서는 섹션을 일반화하여 형태로 표현하고 패턴에 맞게 컴포넌트를 설계하는 방법에 대해 안내한다.

다만 내가 회사에서 참여한 프로젝트는 모두 웹이었기 때문에 모바일에 비해 섹션이 훨씬 다양한 방식으로 표현되어 있었다.

 

하지만 API 구조를 현재의 섹션에 맞게 변환하여 화면에 뿌려주는 방식은 인상적이어서

다음 프로젝트에서 시도해보고 싶다는 생각이 들었다.

 

 

출처: https://fe-developers.kakaoent.com/2023/230330-frontend-solid/

 

 

 

 

🔭 개방 폐쇄 원칙을 위해?!

기획이 완전 엎어지는 경우는 코드 구조 수정이 불가피하겠지만

최대한 코드의 수정을 피하고 확장이 가능한 형태로만 구조를 짜는 습관을 더 가져야 할 것이다.

 

 


 

 

 

다음 포스팅에서는 개방 폐쇄 원칙의 다음 원칙인

리스코브 치환 원칙에 대해 회고를 해볼 것이다.