Atomic Design Mapping

Atomic Design 철학을 Kosmos의 코드 구조와 매핑합니다. Page → Template → Organism(Fragments) → Molecule/Atom(Components) → El.* 순으로 UI와 코드의 계층을 정렬해 일관성과 재사용성을 극대화합니다.

계층 요약

Template

레이아웃/슬롯 제공. 페이지 골격만 담당.

DocsPageTemplate(left, content, rightTOC)

Organism (Fragments)

여러 컴포넌트를 조합한 실질 뷰 조각.

FragDocsNodeTree, FragDocsContent

Molecule/Atom (Components)

한 가지 역할에 집중한 재사용 단위.

CompSaveForm, UnsTable, CompInputText

El.*

HTML 요소 팩토리

El.div(), El.a(), El.table(), ...

구성 도식

Template Organism (Fragments) Molecule/Atom (Components) El.* Page (Template + Fragments) Fragments = Components 집합

Template → Fragment(Organism) → Component(Molecule/Atom) → El.*

코드 심화

// Template
public class DocsPageTemplate implements HtmlComponent {
  private final HtmlComponent left;  private final HtmlComponent content;  private final HtmlComponent rightTOC;
  public DocsPageTemplate(HtmlComponent left, HtmlComponent content, HtmlComponent rightTOC) {
    this.left = left; this.content = content; this.rightTOC = rightTOC;
  }
  @Override public String render(RenderContext ctx) {
    return El.div().css("container").children(
      El.div().css("row").children(
        El.div().css("col-3 d-none d-lg-block").child(left),
        El.div().css("col-9").children(content, rightTOC)
      )
    ).render(ctx);
  }
}
// Fragment (Organism)
public class FragDocsContent implements HtmlComponent {
  private final DocsContentRespDto content;
  public FragDocsContent(DocsContentRespDto content) { this.content = content; }
  @Override public String render(RenderContext ctx) {
    // content.getContent()는 이미 신뢰 가능한 HTML이라는 가정 하에
    return new StringBuilder().append(content.getContent()).toString();
  }
}
// Component (Molecule/Atom)
public class CompDocMeta implements HtmlComponent {
  private final String version; private final String modifiedBy; private final LocalDateTime modifiedAt;
  public CompDocMeta(String version, String modifiedBy, LocalDateTime modifiedAt) {
    this.version = version; this.modifiedBy = modifiedBy; this.modifiedAt = modifiedAt;
  }
  @Override public String render(RenderContext ctx) {
    return El.div().css("d-flex gap-3 small text-muted").children(
      El.span().text("v" + (version == null ? "-" : version)),
      El.span().text("by " + modifiedBy),
      El.span().text(modifiedAt.toString())
    ).render(ctx);
  }
}

운영 팁

상황 권장 이유
화면 공통 레이아웃 Template로 고정, 슬롯만 노출 레이아웃 변경을 한 곳에서 관리
페이지별 조립 Fragment에서 Components 조합 조합 변경이 쉬움
세부 위젯 Component로 캡슐화 재사용·테스트 용이

주의사항

역할 혼재 금지: Template에 데이터 로직/상태 저장을 넣지 마세요.
거대 Organism: Fragment가 비대해지면 하위 Components로 분해하세요.
테스트: Component 단위 스냅샷 테스트로 회귀를 방지하세요.
성능: 대용량 목록은 Pagination/가상 스크롤 등 패턴을 조합하세요.

다음으로