102 lines
8.5 KiB
Markdown
102 lines
8.5 KiB
Markdown
---
|
|
title: Package by Layer vs Package by Feature (Sahibinden Technology)
|
|
source_type: company-tech-blog
|
|
url: https://medium.com/sahibinden-technology/package-by-layer-vs-package-by-feature-7e89cde2ae3a
|
|
archive_url:
|
|
status: raw
|
|
confidence: medium
|
|
tags: [ca-architecture-layout, feature-first, layer-first, package-by-feature]
|
|
related_branches: [feature-architecture-enforcement-rules, feature-skeleton-package-blueprint-contract, feature-domain-feature-onboarding-contract]
|
|
related_projects: [ca-skeleton-operational-contract]
|
|
created: 2026-05-22
|
|
last_reviewed: 2026-05-27
|
|
---
|
|
|
|
# Package by Layer vs Package by Feature (Sahibinden Technology)
|
|
|
|
> Layer: `raw/company-tech-blogs/` — Sahibinden Technology (터키 최대 e-commerce 플랫폼 엔지니어링 블로그, Medium) 의 사례성 비교 글. ca-tmpl 의 feature-first 결정 강화 근거 (단, company-tech-blog 이므로 공식 best practice 아님).
|
|
|
|
## Parent / 활용 branch (필수)
|
|
|
|
| Branch | 이 자료가 정당화하는 결정 |
|
|
|---|---|
|
|
| [[raw/branch-notes/feature-architecture-enforcement-rules]] | "package-by-feature 의 package-private 가시성 활용" 을 ArchUnit 룰로 강제하는 근거 |
|
|
| [[raw/branch-notes/feature-skeleton-package-blueprint-contract]] | `features/{name}` 패키지에서 내부 클래스 가시성을 `public` default 가 아닌 `package-private` 유도하는 blueprint 결정 |
|
|
| [[raw/branch-notes/feature-domain-feature-onboarding-contract]] | 신규 feature 온보딩 시 "한 패키지 내 응집도 + 외부 패키지와의 결합도" 체크리스트 근거 |
|
|
|
|
## 컨텍스트 / 왜 저장했는지
|
|
|
|
ca-tmpl의 feature-first 결정 근거 강화용. 사례 기반(공식 best practice가 아닌 회사 관점)으로 Package-by-Feature의 구체적 이점(encapsulation, navigation)을 비교 정리한 자료.
|
|
|
|
## 출처 / Source
|
|
|
|
- 원본 URL: https://medium.com/sahibinden-technology/package-by-layer-vs-package-by-feature-7e89cde2ae3a
|
|
- 아카이브 URL: (미확보)
|
|
- 저자: M. Enes Oral
|
|
- 조직: Sahibinden Technology (터키 최대 e-commerce 플랫폼 엔지니어링 블로그)
|
|
- 발행일: 2021-06-01
|
|
- 마지막 확인일: 2026-05-27
|
|
|
|
## 핵심 인용 / Key quotes (verbatim)
|
|
|
|
> [§Package by Layer — cohesion] "This method causes low cohesion within packages because packages contain classes that are not closely related to each other."
|
|
|
|
> [§Package by Layer — coupling] "high coupling occurs between packages" (Repository / Service / Controller 의존 맥락에서)
|
|
|
|
> [§Package by Feature — encapsulation] "Package by Feature allows some classes to set their access modifier `package-private` instead of `public`, so it increases **encapsulation**."
|
|
|
|
> [§Package by Feature — navigation] "Package by Feature reduces the need to navigate between packages since all classes needed for a feature are in the same package."
|
|
|
|
> [§Package by Layer — scaling] "As an application grows in size, the number of classes in each package will increase without bound" (Package by Layer 의 한계 설명)
|
|
|
|
## Claims Extracted / 추출된 주장
|
|
|
|
| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove |
|
|
|---|---|---|---|---|---|
|
|
| SAHIBINDEN-PBF-C1 | Package-by-Layer 는 한 패키지 내 클래스들이 서로 밀접하지 않아 **low cohesion** 을 유발한다 | [§Cohesion] "This method causes low cohesion within packages because packages contain classes that are not closely related to each other." | `company-case-study` | Java 백엔드 모놀리스의 패키지 구조 평가 | "모든 layer-first 프로젝트가 low cohesion" 이라는 일반화는 아님 — 도메인이 단일하고 작으면 차이 미미 |
|
|
| SAHIBINDEN-PBF-C2 | Package-by-Layer 는 Repository/Service/Controller 의존 관계로 인해 패키지 간 **high coupling** 이 발생한다 | [§Coupling] "high coupling occurs between packages" | `company-case-study` | layer 기반 패키지 분할 진단 | 정량 측정 (coupling metric, 예: efferent/afferent) 미제시 — 정성적 관찰 |
|
|
| SAHIBINDEN-PBF-C3 | Package-by-Feature 는 일부 클래스의 가시성을 `public` 대신 `package-private` 으로 둘 수 있어 **encapsulation** 이 증가한다 | [§Encapsulation] "Package by Feature allows some classes to set their access modifier `package-private` instead of `public`, so it increases encapsulation." | `company-case-study` | Java 언어의 가시성 제어 활용 | Kotlin/Scala 등 다른 JVM 언어의 가시성 모델에 그대로 적용된다는 뜻은 아님 |
|
|
| SAHIBINDEN-PBF-C4 | Package-by-Feature 는 한 기능에 필요한 클래스가 한 패키지에 모여 있어 **패키지 간 navigation 비용** 을 줄인다 | [§Navigation] "Package by Feature reduces the need to navigate between packages since all classes needed for a feature are in the same package." | `company-case-study` | 개발자 생산성 / IDE 탐색 측면 평가 | navigation 시간 절감의 정량 데이터 (분/일) 미제시 |
|
|
| SAHIBINDEN-PBF-C5 | Package-by-Layer 는 application 규모가 커질수록 각 패키지 내 클래스 수가 **무한정 증가** 하는 한계가 있다 | [§Scaling] "As an application grows in size, the number of classes in each package will increase without bound" | `company-case-study` | 장기 운영 / 규모 확장 시나리오 | "feature-first 는 그렇지 않다" 의 증거는 본 인용 직접 없음 — 별도 분할 정책으로 대응한다는 의미일 뿐 |
|
|
|
|
## Usage Boundaries / 적용 경계
|
|
|
|
- **이 자료가 직접 증명하는 것**:
|
|
- `SAHIBINDEN-PBF-C1~C5`: Sahibinden 엔지니어 (M. Enes Oral, 2021-06-01) 가 Package-by-Layer 의 단점과 Package-by-Feature 의 이점을 정성적으로 진단한 내용
|
|
- **이 자료가 증명하지 않는 것**:
|
|
- "Package-by-Feature 가 공식 표준 best practice" 라는 정당화 — 본 글은 **company-tech-blog** (Strength = `company-case-study`). CLAUDE.md §5 "company-tech-blog → 공식 best practice 로 취급 금지" 명시.
|
|
- feature-first 의 정량 우위 (cohesion/coupling 메트릭) — 본 글은 정성적 관찰
|
|
- Sahibinden 자체의 production 채택 / 운영 측정 결과 — 본 글은 비교 논의, 실제 회사 코드베이스 적용 증거 미수록
|
|
- **내 프로젝트에 적용하려면 추가 확인이 필요한 것**:
|
|
- ca-tmpl 에서 `package-private` 가시성을 실제로 활용하는 비율 — feature 패키지 내 ratio 측정 필요
|
|
- Spring Boot 의 `@Service` / `@Repository` 가 default `public` 가시성을 요구하는지 확인 (component scan 호환성)
|
|
- Sahibinden 외 다른 사례 (Naver / 카카오 / 우아한형제들 등) 의 동일 패턴 채택 여부 — 별도 ingest 필요 (단일 회사 글로 일반화 금지)
|
|
|
|
## 메모 / Notes (내 프로젝트 해석 — 자료 직접 인용 아님)
|
|
|
|
- 적용 시나리오: 도메인 수가 늘어나는 중규모 이상 monolith.
|
|
- 장점: package-private 가시성 활용 가능 → 자바 언어 차원에서 모듈 경계 강제. IDE 탐색 비용 감소.
|
|
- 단점: source_type이 `company-tech-blog`이므로 공식 best practice로 인용 금지. 회사 사례 수준의 신뢰도 (Strength = `company-case-study`).
|
|
- ca-tmpl(feature-first)와의 차이: 인용된 encapsulation 이점은 ca-tmpl이 `features/{featureName}` 패키지를 둔 핵심 명분 중 하나. ca-tmpl은 여기서 한 단계 더 나아가 feature 안에서 다시 layer를 나눈 하이브리드.
|
|
|
|
## 관련 ca-tmpl branch / contract
|
|
|
|
- 적용 branch-note:
|
|
- [[raw/branch-notes/feature-architecture-enforcement-rules]]
|
|
- [[raw/branch-notes/feature-skeleton-package-blueprint-contract]]
|
|
- [[raw/branch-notes/feature-domain-feature-onboarding-contract]]
|
|
- canonical contract 섹션:
|
|
- [[raw/project-notes/ca-skeleton-operational-contract#20. Skeleton Blueprint Contract]]
|
|
- [[raw/project-notes/ca-skeleton-operational-contract#19. Domain Application Readiness Contract]]
|
|
- 대안 그룹: **Topic 1 — Architecture Layout** (대안 5종: feature-first / layer-first / hexagonal / modulith / onion)
|
|
- 본 source의 위치: ca-tmpl 채택안 baseline (feature-first) 의 강화 사례 evidence (공식 표준 아님)
|
|
|
|
## Related / 관련
|
|
|
|
- 같은 주제 다른 official-doc / company-tech-blog:
|
|
- [[raw/official-docs/feature-first-uncle-bob-screaming-architecture-2011]] (feature-first 측 철학 baseline — Uncle Bob)
|
|
- [[raw/official-docs/layer-first-baeldung-clean-architecture-spring-boot]] (대안 layer-first 의 대표 튜토리얼)
|
|
- 인용하는 branch:
|
|
- [[raw/branch-notes/feature-architecture-enforcement-rules]]
|
|
- 인용하는 wiki: (미작성)
|