[클린코드 JS] 09. 추상화 및 캡슐화하기

Serin-B·2023년 6월 30일
0

클린코드JS

목록 보기
9/15
post-thumbnail

추상화

추상화란
'추상'이란 '사물이나 표상을 어떤 성질, 공통성, 본질에 착안하여 그것을 추출하여 파악하는 것' 을 말한다. 즉, 추상화란 핵심적인 개념 또는 공통적인 기능을 추출하는 것을 말한다.
추상화하는 이유
1. 가독성 증가 - 복잡한 로직은 숨기고 간결하게 표현하면 읽기도 쉽고 이해하기도 쉬움
2. 생산성 및 재사용성 증가 - 공통적인 부분을 추출해 잘 만든 클래스 또는 함수는 재사용 가능하며 생산성을 높여줌

예를 들어 여기 메세지 보내기 버튼이 하나 있다. 우리는 메세지가 어떠한 방식으로 어떻게 보내지는지 모르지만, 버튼을 누르면 메세지가 보내진다는 것을(원하는 대로 동작한다는 것을) 안다. 즉, 복잡한 로직은 모두 숨기고, 버튼만 노출해 둔 것이다.

이처럼 기능 구현을 할 때, 복잡한 로직 및 상황은 숨기고, 간결하고 명확하게 단순화 또는 일반화 시키는 것이 바로 추상화이다.

아래는 모달을 html에서 불러오고, css를 변경하고, 모달의 열림을 제어하는 javascript 코드이다. 관심사 분리가 전혀 되어있지 않고, 추상화도 되어있지 않은 상태이다.

// before
const el = document.querySelector('#modal')
el.style.backgroundColor = 'black'
el.classList.add('--open') 
el.classList.remove('--open')

지금은 코드가 짧아서 잘 느껴지지 않을수도 있지만, 코드가 커지고 로직이 복잡해지면 이런 식의 코드는 가독성이 떨어지고, 몹시 끔찍하다.🤢

또한 모달이 여러 개라면 색상을 변경하거나 열고 닫는 제어를 매 모달마다 해줘야한다. 그러나 아래와 같이 반복되는 코드들은 함수로 추상화해두면 편하게 쓸 수 있다. 코드에서 중복을 발견할 때마다 추상화할 기회로 간주하자!

// 리펙토링 
const changeColorBlack = (el) => {
  el.style.backgroundColor = 'black'
}

const openModal = (el) => {
  el.classList.add('--open')
}

const colseModal = (el) => {
  el.classList.remove('--open')
}

const myModal = () => {
  // modal 생성 코드
  return document.querySelector('#modal')
}

changeColorBlack(myModal)
openModal(myModal)
colseModal(myModal)

다음과 같이 적절하게 추상화시켜서 내부 구현을 숨기는 것이 좋다.

우리는 이제 changeColorBlack를 통해 간단하게 배경색을 바꿀 수 있고, openModalcolseModal 을 통해 편리하게 모달을 제어할 수 있다. 전달하는 인자에 다른 모달을 넣으면 그 모달도 간편하게 제어할 수 있다. 심지어 함수 내부에서 어떻게 동작하는지 복잡하게 보이지도 않는다. 추상화는 중복 제거 및 적절한 숨김으로 인해 편리성 뿐만아니라 가독성을 높여준다.

캡슐화

캡슐화란
캡슐은 안에 어떤 색의 내용물이 있는지, 또 어떤 성분의 약이 들어있는지 알 수 없다. 즉, 캡슐화란 특정 부분을 감싸 데이터를 보호하거나 은닉하는 것을 말한다.

캡슐화를 하는 이유
1. 데이터 보호 – 외부로부터 내부에 정의된 속성과 기능들을 보호할 수 있음
2. 데이터 은닉 – 내부의 동작을 감추고 외부에는 필요한 부분만 노출해줌

  • 상수 및 변수를 활용한 캡슐화
// 숫자 캡슐화
const REFRESH_TOKEN_EXPIRATION_TIME = 12 * 60 * 60 * 1000 //12시간

// 휴먼에러(오타 등) 방지를 위한 문자열 캡슐화
const SUPERVISOR ='supervisor'

// 경계 캡슐화
const nextLevel = level + 1

반복되는 숫자 혹은 문자, 경계 등은 상수 및 변수로 선언하여 관리하는 것이 좋다. 훨씬 간결하고 명료하게 표현할 수 있고, 휴먼 에러를 줄일 수 있으며, 추후 변경이 수월하다.

  • 조건의 캡슐화
// 캡슐화 O
if(needDeleted(timer)){}
   
// 캡슐화 X
if(timer.hasExpired()&&!timer.isRecurrent()){}

조건을 캡슐화하면 한 눈에 알아보기 쉽고, 조건이 변경되었을 때 코드 변경이 더 용이하다.

  • 객체 데이터 변경 캡슐화
function setLogin(bool){
  model.isLogin = bool;
}
function setValidToken(bool){
  model.isValidToken = bool
}

function login(){
  setLogin(true);
  setValidToken(true);
}
function logout(){
  setLogin(false);
  setValidToken(false);
}

유명한 상태관리 툴 Redux 에서도 상태를 변경하려면 액션과 리듀서를 써야한다. 데이터를 보호하고 예측가능하게 변경하기 위해서는 다음과 같이 데이터를 변경해주는 함수를 별도로 생성하고, 해당 함수를 통해서만 데이터를 변경해주는 것이 좋다.

마지막으로 추상화와 캡슐화를 떠올리면 생각나는 이미지는 바로 마트료시카 인형이다.

마트료시카 인형처럼 함수를 하나씩 차근차근 벗겨나가다보면 내부 로직 및 동작 원리를 파악할 수 있게 된다. 한 번에 파악하기 쉽지 않지만, 적절한 캡슐화와 추상화가 되어있는 코드라면 내가 원하는 만큼까지 파고들 수 있고, 유지보수도 용이해진다. 따라서 클린 코드를 위해서는 추상화와 캡슐화를 적적하게 활용해야 한다!

profile
프론트엔드 개발자

0개의 댓글

관련 채용 정보