티스토리 뷰

컴포지션(Composition)은 객체지향 프로그래밍(OOP)에서 코드의 재사용성과 확장성을 높이기 위해 사용되는 설계 기법 중 하나로, 클래스를 상속하지 않고, 다른 객체를 포함(Has-A 관계) 하여 그 객체의 기능을 사용하는 방식입니다. 이는 상속(Inheritance)과 대비되는 개념으로, "컴포지션(composition)"을 통해 객체 간 관계를 맺는 것을 의미합니다.

 

특징

Has-A 관계 - 컴포지션은 "A는 B를 가진다"라는 관계를 나타냅니다.
- 예: 자동차 클래스가 엔진 객체를 포함하면, 자동차와 엔진은 "Has-A 관계"에 있습니다.
유연성 - 상속은 강한 결합을 만드는데 반해, 컴포지션은 더 느슨한 결합(Loose Coupling)을 제공합니다.
- 객체를 포함하여 필요에 따라 기능을 추가하거나 교체할 수 있습니다.
다형성 - 컴포지션을 사용하면 포함된 객체를 인터페이스를 통해 참조하여 동적으로 교체하거나 확장할 수 있습니다.
상속보다 더 선호됨 - "상속보다는 컴포지션을 선호하라"는 객체지향 설계의 권고 사항 중 하나로, 필요 이상으로 상속 계층을 복잡하게 만들지 않도록 권장합니다.

 

 

컴포지션과 상속 비교

특징 컴포지션 상속
관계 Has-A (포함 관계) Is-A (상속 관계)
결합도 느슨한 결합 강한 결합
재사용성 구성 요소를 변경하거나 교체하기 쉬움 상속 구조를 변경하면 파급 효과가 큼
다중 사용 여러 객체를 포함할 수 있음 자바에서는 다중 상속 불가능
유연성 더 동적이며 런타임에 객체 교체 가능 컴파일 타임에 고정된 관계
복잡성 코드 설계가 더 명확 상속 계층이 깊어지면 관리가 어려움

 

 

코드 예제

클래스 내부에서 객체를 생성하여 사용

class Engine {
    public void start() {
        System.out.println("Engine started");
    }
}

class Car {
    private Engine engine; // Engine 객체를 포함

    public Car() {
        this.engine = new Engine(); // 내부에서 Engine 객체 생성
    }

    public void startCar() {
        engine.start();
        System.out.println("Car is running");
    }
}

public class Main {
    public static void main(String[] args) {
        Car car = new Car(); // Car 객체 생성
        car.startCar(); // Engine started -> Car is running
    }
}

 

외부에서 객체를 주입받아 사용

class Engine {
    public void start() {
        System.out.println("Engine started");
    }
}

class Car {
    private Engine engine; // Engine 객체를 포함

    public Car(Engine engine) { // 생성자를 통해 Engine 객체 주입
        this.engine = engine;
    }

    public void startCar() {
        engine.start();
        System.out.println("Car is running");
    }
}

public class Main {
    public static void main(String[] args) {
        Engine engine = new Engine(); // Engine 객체 생성
        Car car = new Car(engine);   // Engine 객체를 Car에 주입
        car.startCar();              // Engine started -> Car is running
    }
}

 

외부 주입과 직접 객체 생성하는 방법 비교

특징 내부에서 객체 생성 외부에서 객체 주입
결합도 강한 결합 느슨한 결합
유연성 객체 교체나 확장이 어려움 객체 교체와 확장이 용이
테스트 용이성 포함된 객체를 Mocking하기 어려움 Mock 객체를 주입하여 테스트 가능
사용 편의성 초기 설정이 간단 외부에서 객체를 생성 및 주입해야 하므로 설정 필요
예제 상황 객체가 고정적이고 변경될 가능성이 없을 때 객체를 유연하게 교체하거나 확장해야 할 때

 

'[개발] Info > 용어' 카테고리의 다른 글

믹스인(mixin)에 대해서 알아보자  (0) 2025.01.08
[IT 용어] Server Farm  (2) 2025.01.04
지수적 백오프(Exponential Backoff)  (0) 2024.10.08
멀티 모듈(Multi-Module)  (0) 2024.08.09
Software versioning  (0) 2024.07.28