Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 |
Tags
- 서버리스 #
- npm
- Websocket
- github
- jwt
- Strict
- es6
- 데이터베이스 #try #이중
- 전역변수
- 당근마켓
- 으
- 0.75px border
- 10px
- 타입스크립트
- Props
- 1px border
- entity
- literal
- TS
- 클론코딩
- TypeScript
- &연산
- font-size
- 컴포넌튼
- ES5
- 문서번호
- 0.25px border
- ZOOM
- 0.5px border
- angular
Archives
- Today
- Total
복잡한뇌구조마냥
[JAVA] 구성 ( Composition ) 본문
✅ 개요
Composition(구성) 은 객체지향 프로그래밍에서 객체 간 관계를 형성하는 중요한 설계 기법입니다.
보통 자바에서 객체 간 재사용을 구현할 때 흔히 상속(inheritance)을 떠올리지만, Composition은 상속보다 더 유연하고 유지보수가 쉬운 설계 방식으로 권장되는 경우가 많습니다.
🔍 1. Composition이란?
Composition이란 다른 객체를 자신의 필드로 포함하여 기능을 위임(Delegate)하는 방식입니다.
즉, "has-a" 관계를 나타냅니다.
class Engine {
public void start() {
System.out.println("Engine starting...");
}
}
class Car {
private Engine engine = new Engine(); // Car has-a Engine
public void drive() {
engine.start(); // 기능 위임
System.out.println("Car is driving...");
}
}
📌 Car는 Engine을 상속받지 않았지만, 내부에 포함(Composition)시켜 기능을 사용하고 있습니다.
2. 상속(Inheritance) vs 구성(Composition) 🆚
항목 | 상속 (Inheritance) | 구성 (Composition) |
관계 | "is-a" 관계 | "has-a" 관계 |
유연성 | 낮음 (강한 결합) | 높음 (약한 결합) |
재사용성 | 부모 클래스에 종속적 | 독립적 재사용 가능 |
변경에 대한 유연성 | 취약 | 견고 |
예시 | Bird extends Animal | Bird has-a Wing |
📌 Composition은 실행 중(runtime)에 객체를 바꿀 수 있어 동적으로 행동을 바꾸기 쉽습니다.
🚫 3. 상속의 한계
class Printer {
public void print() {
System.out.println("Printing...");
}
}
class FaxPrinter extends Printer {
public void fax() {
System.out.println("Faxing...");
}
}
이 방식은 언뜻 보면 괜찮아 보이지만...
- FaxPrinter는 Printer의 모든 기능에 종속됩니다.
- 만약 Printer의 기능이 바뀌면, FaxPrinter도 영향을 받습니다.
- 코드 수정 시 영향 범위가 넓습니다.
✅ 4. Composition을 활용한 리팩토링
class Printer {
public void print() {
System.out.println("Printing...");
}
}
class Fax {
public void fax() {
System.out.println("Faxing...");
}
}
class FaxPrinter {
private Printer printer;
private Fax fax;
public FaxPrinter() {
this.printer = new Printer();
this.fax = new Fax();
}
public void print() {
printer.print();
}
public void fax() {
fax.fax();
}
}
이제 FaxPrinter는 필요한 기능만 조합하여 사용할 수 있으며,
Printer나 Fax의 변경이 있어도 영향을 최소화할 수 있습니다.
🎯 5. Composition의 장점 요약
- ✅ 유연성: 기능을 조합해서 동적으로 행동을 바꿀 수 있음
- ✅ 재사용성: 여러 클래스에서 같은 객체 조합 가능
- ✅ 의존성 분리: 각 컴포넌트는 독립적으로 테스트 가능
- ✅ SOLID 원칙 중 DIP/ISP 만족: 상위 모듈에 의존하지 않음
🧠 실무 팁
- 상속은 정말 “is-a” 관계일 때만 사용하세요.
- 구현보다 인터페이스를 활용한 Composition이 더욱 유연합니다.
- 다양한 라이브러리나 프레임워크에서도 Composition 기반 설계가 일반적입니다 (ex. Spring DI).
📝 마무리
상속은 너무 강한 관계입니다.
변화에 강하고 테스트 가능한 코드를 짜기 위해선 Composition 중심의 객체 설계를 고려해보세요.
“상속보다는 조합을 사용하라 (Favor Composition Over Inheritance)”
— Effective Java
LIST
'BE > JAVA' 카테고리의 다른 글
[JAVA] Effective Java - 다 쓴 객체 참조를 해제하라 (7) (3) | 2025.08.03 |
---|---|
[JAVA] 반복문 간결하게 쓰는 법 - 람다와 메서드 참조로 리팩토링 (2) | 2025.07.29 |
[JAVA] 스트림 ( Stream ) (0) | 2025.07.28 |
[JAVA] 자주 사용하는 자료형 핵심 메소드 정리 (1) | 2025.07.14 |
[JAVA] n진수 변환, 변환 정리 (String ↔ 숫자형) + 3진법 뒤집기 (0) | 2025.07.03 |