[Front-end] 개발자 공부

[개발 공부 88일차] 함수형 코딩 | 계층형 설계 II

MOLLY_ 2024. 8. 26. 16:16
728x90

< 목차 >

[들어가며] 알아둬야 할 개념

0. TL;DR

1. 추상화 벽

2. 작은 인터페이스

3. 편리한 계층

4. 호출 그래프

 

 

 

[들어가며] 알아둬야 할 개념

  • 소프트웨어 설계(software design): 코드를 만들고, 테스트하고, 유지 및 보수하기 쉬운 프로그래밍 방법을 선택하기 위해 미적 감각을 사용하는 것
  • 계층형 설계(stratified design): 바로 아래 계층에 있는 함수로 현재 계층의 함수를 구현해, 소프트웨어 코드를 계층으로 구성하는 기술

 

 

0. TL;DR

  1. 추상화 벽: 신경 쓰지 않아도 되는 부분을 나누고, 계층 간의 역할과 책임을 명확히 하는 것
    • [효과] 팀 간 커뮤니케이션 비용을 줄이고, 복잡한 코드를 명확히 함
  2. 작은 인터페이스: 추상화 벽에 있는 코드를 최소화하고, 새로운 기능은 추상화 벽 위 계층에 구현하는 것
    • 중요한 비즈니스 개념을 표현하는 인터페이스는 한 번 만들어 놓고, 변경하거나 늘어나지 않아야 함
  3. 편리한 계층: 언제 계층형 설계 패턴을 적용하고, 멈춰야 하는지에 대한 실용적인 방법
  4. 호출 그래프 구조에서 규칙을 얻을 수 있음
    • 어떤 코드를 테스트하는 게 가장 좋은지 or 유지/보수 혹은 재사용하기 좋은 코드는 어디에 있는 코드인지 알 수 있음

 

 

아무리 봐도 구글 진짜 검색에 따른 답변 찾는 퀄리티 짱 좋아진 듯

 

 

1. 추상화 벽

: 세부 구현을 감춘 함수로 이뤄진 계층

추상화 벽이 있으면 구체적인 걸 신경쓰지 않아도 된다.

 

“해당 계층에 직접적인 영향이 없는 값은 신경 쓰지 않아도 된다 (= 무시)”

그래서 아래 예시처럼 추상화 벽의 경계를 넘나드는 경우는 없어야 한다. 신경 쓰지 않아야 할 세부적인 구현을 하고 있는 것이다.

 

 

추상화 벽 위에 있는 코드와 아래에 있는 코드를 벽을 기준으로 나눠서 서로에 대한 의존성을 없앴다. 따라서, 위에 있는 코드는 구체적인 내용(e.g. 데이터 구조)을 무시해도 된다.

 

👾 [참고] 아래쪽으로 가리키는 화살표가 많은 함수는 재사용하기 어려움

👾 실제 사용한 유사 사례를 보고 싶다면 <토스 | 레고처럼 조립하는 토스 앱 - https://toss.tech/article/slash23-iOS>를 참고하자

 

 

[예시] 데이터 구조 변경 (배열 → 객체)

예를 들어, 데이터 검색 로직이 필요한데 배열로 데이터 구조를 짰다고 하자.

 

배열로 순서대로 검색하는 건 비효율적이기 때문에 더 빨리 찾을 수 있는 데이터 구조인 ‘객체를 해시 맵처럼 사용하는 것’이 확실한 방법이다. 객체에서 항목을 추가, 삭제, 해당 항목이 있는지 확인하는 동작 모두 빠르다.

 

여기서 추상화 벽이 의미하는 건 추상화 벽 위에 있는 함수는 데이터 구조가 변경된단 사실을 몰라도 된다는 것이다. 직접적인 영향이 없기 때문에 무시해도 된다.

 

 

추상화 벽, 언제 사용?

필자는 ‘언제’ 사용해야 하는 게 좋은지를 설명해야 하는데, ‘왜’ 사용하면 좋은지를 나열하고 있길래 본문에서 언제 사용하면 될지 내가 따로 추려내 보았다.

 

  1. 최선의 구현임을 확신할 수 없는 경우: 구현을 간접적으로 사용할 수 있기에 나중에 코드를 변경하기 쉬움
  2. 뭔가 바뀔 걸 알고 있지만 아직 준비되지 않은 경우: 단, 미래를 대비하고자 함이라면 변경이 확실한 경우에만 작성하여 쓸데없는 코드를 줄이자
  3. 코드를 읽고, 쓰기 쉽게 만들고 싶은 경우: 세부적인 부분은 신경 쓰지 않아도 돼서 복잡한 코드를 명확히 할 수 있음
  4. 서로의 코드에 의존성을 없애, 팀 간에 역할과 책임을 명확히 하고 싶은 경우: 팀 간 커뮤니케이션 비용 감소 효과 있음

 

 

2. 작은 인터페이스

: 새로운 코드를 추가할 위치로, 하위 계층에 불필요한 기능이 쓸데없이 커지는 걸 방지

 

새로운 기능을 구현할 때, 추상화 벽 위에 있는 계층에 구현하는 것이 더 좋다.

하위 계층을 고치지 않고 상위 계층에서 문제를 해결할 수 있어, 추상화 벽 뿐만 아니라 모든 계층에 적용할 수 있다.

 

 

인터페이스를 적게 만들어야 하는 이유

추상화 벽에 만든 함수는 ‘인터페이스’라고 할 수 있다.

 

  1. 추상화 벽에 코드가 많으면
    1. 구현이 변경됐을 때, 고쳐야 할 코드가 많음
    2. 팀 간 조율해야 할 게 많아짐
    3. 알아야 할 게 많아서 사용하기 어려움
  2. 추상화 벽에 있는 코드는 낮은 수준의 코드이기 때문에
    1. 더 많은 버그가 있을 수 있음
    2. 이해하기 더 어려움

 

 

3. 편리한 계층

: 언제 계층형 설계 패턴을 적용하고, 멈춰야 하는지에 대한 실용적인 방법

  • 멈춰도 될 때: 작업하는 코드가 편리하다고 느낄 때
  • 적용해야 할 때: 구체적인 걸 너무 많이 알아야 할 때, 코드가 지저분하다고 느낄 때

 

위 내용만 딸랑 있는 거 보고 내가 졸려서 잘못 봤나 싶었다… 필자도 이거 작성하다 졸은 걸까?.. 계층형 설계 패턴 4가지에 이걸 왜 추가했을까,, 3가지로 하고 따로 첨언해도 됐을 듯. 그리고 전체적으로 설명이 너무 아쉽다

 

 

4. 호출 그래프

호출 그래프 구조는 3가지 중요한 비기능적 요구사항을 보여준다.

 

비기능적 요구사항: 테스트를 어떻게 할 것인지, 재사용을 잘할 수 있는지, 유지보수하기 어렵지 않은지와 같은 요구사항 (소프트웨어 설계를 하는 중요한 이유임)

  1. 유지보수성: 요구 사항이 바뀌었을 때, 가장 쉽게 고칠 수 있는 코드는 어떤 코드인가
  2. 테스트성: 어떤 걸 테스트하는 게 가장 중요한가
  3. 재사용성: 어떤 함수가 재사용하기 좋은가

⇒ 위 3가지 답: 가장 낮은 곳의 코드

 

 

👾 기능적 요구사항: 소프트웨어가 정확히 해야 하는 일 (e.g. 세금 계산을 했을 때, 올바른 계산 결과가 나와야 함)

👾 테스트는 왜 해야 할까? 어떤 걸 테스트 하는 게 좋을까? 라는 의문을 가지고 있다면 <토스 | 프론트엔드 개발에서 테스트 자동화, 꼭 해야 할까? - https://toss.tech/article/28580>를 참고하자

 

 

호출 그래프 위치에 따른 차이 및 중요성

[예시] 토스 iOS 앱의 계층 구조

 

  1. 가장 높은 곳에 있는 코드: 자주 바뀌는 요구사항(e.g. 비즈니스 규칙) 코드를 작성
    • 어디에서도 호출하지 않기 때문에 고치기 가장 쉬움 ⇒ 다른 코드에 영향 없음
    • 바뀌는 게 많은, 가장 높은 코드는 적게 유지하는 게 좋음
  2. 가장 낮은 곳에 있는 코드: 시간이 지나도 변하지 않는 코드를 작성
    • 위에 너무 많은 코드를 만들어서, 수정하기 힘듦
    • 낮은 계층의 함수의 코드를 수정하면, 연결된 상위 동작들이 모두 변경됨
    • 가장 아래의 코드를 테스트하는 게 중요! ⇒ 많은 코드가 가장 아래의 코드를 의존

 

 

 

728x90