본문 바로가기
[CS] - Design Pattern

#3. 컴포지트 패턴 (Composite Pattern)

by Bebsae 2021. 1. 19.

컴포지트 패턴은 복합 객체와 단일 객체를 클라이언트에서 구별없이 다루게 해주는 패턴이다. (일종의 일반화를 위한 인터페이스를 정의)

OCP(Open-Closed Principal)을 준수하기에 용이하다. (변화에는 닫혀있고, 확장에는 열려있다.)

public class Computer {
    private Keyboard keyboard;
    private Body body;
    private Monitor monitor;
    
    ...
}

위와 같은 코드는 확장에 용이하지 못하다. 그 이유는 Keyboard, Body, Monitor의 공통된 타입이 존재하지 않기 때문이다.

(컴퓨터라는 전체 시스템의 부분집합이라는 공통점이 존재함에도 불구하고)

 

단점 : 공통점(부분집합)으로 묶은 인터페이스에 공통되는 기능들은 메소드 멤버를 정의하면 되는데 위와 같은 코드는 각 클래스마다 공통되는 기능들 마저 일일이 정의해야한다. 그 뿐만 아니라 공통된 타입이 없으므로 하나의 자료구조에 담을 수 없다.

 

이를 해결하려면? 각 부분집합 장비들에 대해 인터페이스나 추상클래스를 정의하면 된다.

// 부분집합의 추상클래스
public abstract class ComputerDevice {
    // 공통되는 기능들을 묶을 수 있는 일반화의 위력
    public abstract int getPrice();
    public abstract int getPower();
}
public class Keyboard extends ComputerDevice {
    ...
    
    public int getPrice(){
        // 구현부
    }
    pubic int getPower() {
        // 구현부
    }
    
    ...
}

public class Body extends ComputerDevice {
    ...
    
    public int getPrice(){
        // 구현부
    }
    pubic int getPower() {
        // 구현부
    }
    
    ...
}

public class Monitor extends ComputerDevice {
    ...
    
    public int getPrice(){
        // 구현부
    }
    pubic int getPower() {
        // 구현부
    }
    
    ...
}

각 부품들은 다른 기능들이 있을 것이다. 그런 기능들만 각 클래스에서 별도로 정의하고 공통되는 기능(getPrice(), getPower())는 추상 클래스로부터 상속받아 구현하면 된다.

 

public class Computer {
    // 각 장비들을 ComputerDevice라는 공통 추상 클래스로 일반화 : 타입의 구분이 없어짐.
    private List<ComputerDevice> components = new ArrayList<ComputerDevice>();
    
    public addComponent(ComputerDevice component) {
        components.add(component);
    }
    
    ...
}

 

이제 클라이언트에서 일반화의 위력을 보자.

public class Client {
    public static void Main(String[] args) {
        Computer computer = new Computer();
        
        Keyboard keyboard = new Keyboard();
        Body body = new Body();
        Monitor monitor = new Monitor();
        
        // 하나의 자료구조(ArrayList)에 다룰 수 있는 일반화의 위력
        computer.addComponent(keyboard);
        computer.addComponent(body);
        computer.addComponent(monitor);
        
        ...
    }
}

 

댓글