[하루 한 시간] 선언형 블로그 글 정리

이종호·2025년 10월 4일

하루 한 시간

목록 보기
5/13

그래서 DECLARATIVE가 뭔데? - 원지혁

  • 소개: '선언형'이라는 모호한 개념 명확하게 파헤치기
  • React같은 프레임워크의 핵심 철학이지만 정확히 무엇인지 말하기 어려움
  • 핵심은 '어떻게'가 아니라 '무엇을'에 있다.
  • '선언형'접근법의 가장 중요한 본질은 '어떻게'구현할지에 대한 상세한 절차는 추상화하고, '무엇을' 보여주고 싶은지에 대한 최종 결과에만 집중하는 것
// 명령형으로 짠 DOM 명령어
const greeting = "Hello, Imperative!";
const p = document.createElement("p");
p.textContent = greeting;
const app = document.getElementById("app");
app.appendChild(p);
  • 이 코드는 "p태그를 만들고, 컨테이너를 찾아서, 그 안에 p태그를 추가하라"는 식으로 브라우저에게 단계별 지시를 내립니다.
  • 우리가 브라우저가 '어떻게' 일해야하는지 알려주는 셈
// 선언형(Declarative) 코드 예시 (React/JSX)
function Greeting() {
  const greeting = "Hello, Declarative!";
  return <p>{greeting}</p>;
}
  • React가 어떻게 를 내부적으로 처리합니다.

  • 우리는 지시를 내리지 않음

  • 그저 최종적으로 UI가 무엇이어야 하는지 선언할 뿐

  • 즉 "인사말을 담고 있는 p태그가 필요하다"고 말하는 것.

  • 복잡한 DOM조작 과정, 즉 '어떻게'에 해당하는 부분은 React라이브러리가 완전히 추상화하여 대신 처리해줌.

  • '관신삼의 분리'기준이 바뀐다. 기술이 아닌 기능으로

  • 과저에는 관심사 분리는 역할에 따라 HTML, CSS, Javascript 로 나뉘었음

  • 이는 각 기술의 역할과 문법이 명확히 달랐기에 자연스러운 기준.

  • 하지만 React의 JSX와 같은 선언형 UI패턴이 등장하면서 이 기준은 근본적으로 바뀌었음

  • 자바스크립트를 마크업처럼 작성할 수 있게 되면서 기술 간의 경계가 허물어졌기 떄문.

  • 이제 기술이 아닌 '하나의 기능' 또는 '하나의 컴포넌트'를 기준으로 관련된 모든 코드(구조, 스타일, 동작)을 한 곳에 묶는 방식이 더 효율적인 '관심사의 분리'로 여겨짐

  • 이러한 변화가 더 논리적인 이유는?

  • "우리가 보통 앱에서 표현하고자 하는 것이 트리 구조가 아니기 때문"

  • 우리가 표현하고자 하는 것은 바로 정보이다.

  • 과거의 방식은 코드를 기술 중심으로 구성했지만, 새로운 방식ㅇ느 사용자가 마주하는 정보 쪼는 기능을 중심으로 코드를 구성합니다.

  • '프로필 카드'라는 하나의 기능을 구현하는 데 필요한 모든 코드가 한 파일에 모여 있다면, 울니느 제품의 구조와 코드의 구조를 일치시킬 수 있습니다.

  • 이는 코드 응집도를 높여 이해와 유지보수를 훨씬 용이하게 합니다.

  • 하지만 그 기능의 가장 큰 관심사가 복잡한 데이터를 가져오고 관리하는 것이라면 어떻게 해야하나? 선언적 사고방식의 다음 진화는 이 문제를 해결한다.

  • UI를 넘어 데이터까지: 선언현 패러다임의 확장.

  • 선언현 패러다임은 UI를 넘어 데이터 관리 영역으로 자연스럽게 확장됨.

  • 예를 들어 사용자가 소셜 미디어 앱에서 프로필 이미지를 변경했다고 상상해보자.

  • 피드를 스크롤하다 보면 오래된 글에느 ㄴ이전 이미지가, 새 글에는 바꾸니 이미지가 보이는 데이터 불일치 상황이 발생할 수 있슴

  • 이 문제를 해결하기 위해 '단일 진실 공급원' 개념이 등장함

  • 하지만 여러 컴포너트가 서로 얽힌 복잡한 데이터 그래프의 일부를 필요로 할 떄, 이 데ㅐ이터를 가져오고, 정규화하고, 일관성을 유지하는 '어떻게'의 문제가 여전히 남음

  • "리액트가 UI렌더링의 'How'를 가져갔던 것처럼, GraphQL은 데이터 처리의 'How'를 가져갈 수 있음"

  • UI는 컴포넌트는 자신이 필요한 데이터가 무엇인지를 GraphQL 조각 문법으로 코드 바로 옆에 선언하기만 하면 됩니다.

  • 이는 2장에서 다룬 '지능 중심의 관심사 분리'개념의 궁극적인 확장이비다.

  • 이제 컴포넌트는 자신의 렌더링 로직 뿐만 아니라 데이터 의존성 까지 한 곳에서 관리하게 됩니다.

  • 데이터를 네트워크에서 가져오고, 중복을 제거하며 정규화하고, 데이터가 변경되었을 때 관련된 모든 UI를 자동으로 업데이트하는 복잡한 과정은 Relay나 Apollo 같은 GraphQL 기반 라이브러리가 알아서 해줌.

  • 결과적으로 개발자는 데이터 관리의 복잡성에서 벗어나 비즈니스 로직과 사용자 경험을 반드는데 더 집중 할 수 있다.

  • 결론: 좋은 코드란 "What"을 명확하게 드러내는 것
  • 선언형이란 특정 기술이나 라이브러리의 이름이 아님.
  • 그것은 공통된 어떻게를 잘 분석하고 추상화하고, 내 코드에 오직 무엇을 하려하는지에 대한 의조만 명확하게 남기는 사고방식.
  • 로그인 여부를 확인하는 로직이 라우트 핸들러에 직접 섞여 잇었음
// 로그인 여부를 체크하고 리다이렉트하는 로직
app.use((req, res, next) => {
    if (!req.user) {
        res.redirect("/login");
    } else {
        next();
    }
});
  • '어떻게'와 '무엇을'이 뒤엉켜 코드의 핵심 의도를 파악하기 어려움.
  • 이 로직의 '어떻게'를 재사용 가능한 함수로 추상화하면, 의도는 극적으로 명확해짐.
// 'How'를 추상화한 미들웨어
app.use(redirectIf((req) => !req.user, "/login"));

const redirectIf = (compare, to) => {
  return (req, res, next) => {
    if (compare(req)) {
      res.redirect(to);
    } else {
      next();
    }
   }
} 
  • redirectIf가 어떻게 라는 조건부 로직을 담당하면서, 라우트 정의는 어떤 조건에서 리다이렉트할 것인가라는 무엇을 만 선언하게 됨.

느낀점

  • 일단 tanstack-query사용하는 코드라도 따로 커스텀 훅으로 분리해서 과련 코드가 안보이게하는 단계라도 진행해봐야겠다.
  • 이게 도메인 뭐시기에 자꾸 집착하니까 한 걸음도 제대로 때지 못하게 되는것 같다.
profile
코딩은 해봐야 아는 것

0개의 댓글