[클린코드] 11장 : 시스템

목록으로 돌아가기

소프트웨어어에 시스템을 설계한다고 생각해보자.

→ 각 분야별로 시스템을 모듈화 할 것이며, 서로 이를 공유해야한다. 이 때 시스템들이 비슷한 수준의 추상화를 이룬다면 협업이 더 수월해질 것이다. 코드를 깨끗이 유지한다면 낮은 추상화 수준에서 관심사를 분리하기 쉬워진다.

  • 시스템의 생성과 사용을 분리하라
    • 시스템 제작, 즉 생성은 사용과 매우 다르다.
      • 시스템의 객체 생성 및 준비 로직은 런타임 로직과 분리해야한다.
      • 이를 통해 의존성을 해결하고, 모듈성을 높힐 수 있다.
    • 메인 분리
      • 생성과 관련된 코드를 모두 메인이나 이를 호출하는 모듈로 옮긴다.
      • 나머지는 모든 의존성이 연결되었다고 가정해도 된다.
      • 즉 사용되는 어플리케이션은 객체의 생성 과정을 전혀 모른다.
    • 팩토리
      • 어플리케이션에서 객체가 생성되는 시점을 결정해야한다면, 팩토리를 쓰자
      • 팩토리 객체를 만들어서 전달하되, 구현을 숨기고 싶다면 추상 팩토리를 사용하자
      • 그리하여 어플리케이션은 생성 시점을 결정하며, 생성 과정은 모르게 된다.
    • 의존성 주입
      • 제어 역전 기법을 의존성 관리에 적용한 메커니즘
        • 제어역전 기법(IoC) - 상호 의존성을 최소로 가져가며, 프레임워크로 의존성에 대한 제어를 옮기는 것.
        • 의존성을 필요로 하는 객체가 직접 해결하는 대신 컨테이너 및 프레임워크 등이 의존성을 해결해주도록 한다.
    • 확장
      • 처음부터 올바른 시스템을 만들기는 어렵다.
        • 반복적으로 점진적으로 확장해나가는 것이 좋다.
        • 관심사를 적절히 분리하여 관리하면 소프트웨어 아키텍처는 점진적으로 발전할 수 있다.
      • 횡단 관심사
        • 이론적으로는 독립된 형태로 구분될 수 있지만 실제로는 코드에 산재하기 쉬운 부분
        • AOP란 횡단 관심사에 대처하여 모듈성을 확보하는 방법론
        • “특정 관심사를 지원하려면 시스템에서 특정 지점들이 동작하는 방식을 일관성 있게 바꿔야 한다” 라고 명시, 이러한 관점이라는 개념으로 모듈 구성

  • 횡단 관심사를 해결하기 위한 3가지 방법
    • 자바 프록시
      • 단순한 상황에 적합, 객체나 클래스에서 메서드 호출을 감싸는 경우에 좋음
      • 단, 직접 구현 시 깨끗한 코드로 작성하기 어렵다.
    • 순수 자바 AOP 프레임워크
      • 프록시 코드 대부분이 비슷하여 자동화가 쉽다
      • 테스트가 더 쉽고 간단하다.
      • 몇몇 세부 속성들은 annotation으로 클래스로 정의되어있지만, annotation을 벗어나지 않는다. 그러므로 더 깨끗한 코드로 작성할 수 있다.
    • AspectJ 관점
      • 관심사를 관점으로 분리하는 강력한 도구 언어

  • 테스트 주도 시스템 아키텍처 구축
    • 코드 수준에서 아키텍처와 분리가 가능하다면 테스트 주도 아키텍처 구축이 가능해진다.
    • 단순하게 결과물을 낸 후 기반을 조금씩 확장해나가도 좋다.
    • 관점을 효과적으로 분리한다면 확장이 가능해진다.

  • 의사결정을 최적화하라
    • 최대한 정보를 모아 성급하지 않게 최선을 결정을 내리는 것이 좋다.
    • 시기가 되었을 때, 책임자에게 결정을 미루는 것이 고객 피드백과 고통을 줄여줄 것이다.

  • 명백한 가치가 있을 때 표준을 현명하게 사용하라
    • 표준을 사용하면 아이디어 및 컴포넌트 등의 재사용성이 늘며, 여러 이득을 취할 수 있다.
    • 하지만, 이러한 표준에 집착하는 것은 옳지 않으며, 필요할 때에만 사용하도록 노력하자.

  • 시스템은 도메인 특화 언어가 필요하다
    • DSL(Domain Specific Languages)를 사용하여 개념과 구현의 코드 사이 의사소통 간극을 줄이자.

본문에 대한 예시

예시로 제일 잘 볼 수 있는 부분은 관심사 분리 부분 및 메인 분리 부분이다. 특히 관심사 분리는 본문에서 다루고 있는 제작과 사용의 분리를 어플리케이션, 함수 뿐 아니라 웹/앱에서 스타일에도 적용이 가능하다.

function Chip({ isSelected, name, itemClicked }: ChipProps) {
	...
  return (
    <div
      className={
        isSelected
          ? isHovered
            ? "selected-hovered"
            : "selected"
          : isHovered
          ? "unselected-hovered"
          : "unselected"
      }
      onClick={buttonClicked}
      onMouseEnter={() => {
        setIsHovered(true)
      }}
      onMouseLeave={() => {
        setIsHovered(false)
      }}
    >
      {name}
    </div>
  )
}

위 함수에서 스타일로 사용하고 있는 css를 따로 파일로 뽑아서 아래와 같이 관리한다.

.selected {
  display: inline-block;
  border: 1px solid var(--primary-color);
  border-radius: 100px;
  text-align: center;
  padding-top: 5px;
  padding-bottom: 5px;
  padding-left: 7px;
  padding-right: 7px;
  margin: 3px;

  background-color: white;
  color: var(--primary-color);

  font-size: 0.8em;

  /* 글자 스크롤 방지 */
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  -khtml-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}

.selected-hovered {
...
}

이렇게 관리한다면, 함수는 스타일이 어떻게 생성되었는지 과정을 알 수 없으며, 오로지 사용만 하게 된다. 이 역시도 관심사 분리에 해당된다.

function ChipSelector({ title, initialSelectedMember, memberList, setMember }: ChipSelectorProps) {
...
  return (
    <div className="menu-container">
			...
      <div className={"chip-container"}>
        {currentChips &&
          currentChips.map((item) => {
            return (
              <Chip
                index={item.index}
                key={item.index}
                isSelected={item.isSelected}
                name={item.name}
                itemClicked={() => itemSelectStateToggle(item.index)}
              />
            )
          })}
      </div>
    </div>
  )
}

칩을 만들어주는 함수도 칩을 골라서 사용하는 함수에 사용되는데, 이 때에도 이 칩이 어떻게 생성되는지는 칩 사용 함수가 알 수가 없게 된다. 이렇게 거슬러 올라라면 메인에서도 특정 함수 및 컴포넌트의 사용 및 생성이 분리되어 적용할 수 있게 된다.

그리하면 코드를 조금 더 서사적으로 작성이 가능하다. 또한 관점도 분리할 수 있게 되므로, 코드를 이해하는 데에 있어 더욱 수월할 것이다.

author-profile
Written by 상 한규

댓글