구성(Composition)은 기존의 클래스를 새로운 클래스의 구성 요소로 활용하는 방법이다. 그렇기 때문에 여러 클래스에서 코드를 재사용할 수 있어 코드의 중복을 줄일 수 있다.

그림에서 자동차와 운송수단의 관계는 자동차는 운송수단 중 하나기 때문에 서로 is 관계이다.
자동차와 엔진과의 관계는 ? 자동차의 부품 중 하나가 엔진이다. 이를 has 관계라고 한다.
has 관계가 성립되면 하나의 클래스 안에 다른 클래스의 객체를 포함시키면 된다.
햄버거 세트를 생각해보자. 햄버거 세트는 햄버거와 콜라를 가지고 있다.
public class Burger {
private String name;
private int price;
public Burger(String name, int price) {
this.name = name;
this.price = price;
System.out.println(name + "가 만들어졌어요");
}
public String getName() {
return name;
}
public int getPrice() {
return price;
}
}
public class Coke {
private String name;
private int price;
public Coke(String name, int price) {
this.name = name;
this.price = price;
System.out.println(name + "가 만들어졌어요");
}
public String getName() {
return name;
}
public int getPrice() {
return price;
}
}
getName 과 getPrice 메서드는 변수 name 과 price 가 private 로 만들어졌기 때문에 값을 확인할 때 호출할 메서드다.
이 코드를 메인에서 호출하면 버거와 콜라가 호출이 된다.
public class BurgerApp {
public static void main(String[] args) {
Burger burget1 = new Burger("불고기 버거", 2000);
Coke coke1 = new Coke("콜라", 1000);

이때 따로 주문 하는게 아니라 세트로 주문하고 싶다면 햄버거 세트 클래스를 만들어보자.
public class BurgerSet {
private Burger burger;
private Coke coke;
public BurgerSet(Burger burger, Coke coke) {
this.burger = burger;
this.coke = coke;
System.out.println(burger.getName() + "세트가 만들어졌어요");
}
public Burger getBurger() {
return burger;
}
public Coke getCoke() {
return coke;
}
}
Burger 클래스와 Coke 클래스를 가져와 새로운 클래스를 만들었다.
이제 각 클래스에 있는 메서드를 활용해 햄버거 세트를 만들 수 있다.
public class BurgerApp {
public static void main(String[] args) {
BurgerSet set = new BurgerSet(new Burger("데리버거", 2000), new Coke("코카콜라", 1500));
}
}
BurgerSet 클래스를 호출하면 내부의 burger 타입과 coke 타입을 입력받아야 한다.
Burger burger = new Burger() 와 동일하기 때문에 값을 입력했다.

이번에는 입력받은 값으로 햄버거 세트 가격을 표시해보자.
public int getTotalPrice() {
return (getBurger().getPrice() + getCoke().getPrice());
}
BurgerSet 클래스에 총 가격을 확인할 수 있는 코드를 만들었다.
이제 총 가격을 출력해보자
public class LotteApp {
public static void main(String[] args) {
BurgerSet set = new BurgerSet(new Burger("불고기버거", 2000), new Coke("코카콜라", 1500));
System.out.println("총가격" + set.getTotalPrice());
}
}

구성(Composition)을 이용하면 객체의 내부는 공개되지 않고 인터페이스를 통해 코드를 재사용하기 때문에, 구현에 대한 의존성을 인터페이스에 대한 의존성으로 변경하여 결합도를 낮출 수 있기 때문이다.
Share article