Atomic Design Mapping
Atomic Design 철학을 Kosmos의 코드 구조와 매핑합니다. Page → Template → Organism(Fragments) → Molecule/Atom(Components) → El.* 순으로 UI와 코드의 계층을 정렬해 일관성과 재사용성을 극대화합니다.
계층 요약
Template
레이아웃/슬롯 제공. 페이지 골격만 담당.
DocsPageTemplate(left, content, rightTOC)Organism (Fragments)
여러 컴포넌트를 조합한 실질 뷰 조각.
FragDocsNodeTree, FragDocsContentMolecule/Atom (Components)
한 가지 역할에 집중한 재사용 단위.
CompSaveForm, UnsTable, CompInputTextEl.*
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/가상 스크롤 등 패턴을 조합하세요.
다음으로
- Components — 표준 컴포넌트 모음
- Page Template & Slots — 레이아웃/슬롯 구성
- Recipes — 실전 예제