소프트웨어 개발/Design Pattern

④ 디자인 패턴(Design Pattern) - Composite

늘근이 2015. 8. 17. 22:10

Composite 패턴은 마치 나무와 같다. 바로 트리구조라는것.

Composite Pattern

자꾸 여기저기서 트리구조라고 하기 때문에 더 헷갈리는것 같기도 하다. 그렇지만 뭐 해보겠다.

일단 부품이 있다. Component라고 하자.

그 부품 종류에는 계속 부품을 꽂을 수 있는 Composite, 그리고 더이상 부품을 꽂을 수 없어 끝나는 Leaf 부품이 있다. (트리구조라 보통 이렇게 예를 잡는듯 하다.)

즉, Composite을 이용한다면 계속 부품을 꽂아서 객체를 만들어나갈수 있고, Leaf를 이용한다면 거기는 막다른 부품(?)이다.

일단 다음과 같은 기본 부품을 하나 만들어주자.


Component

public interface Component {
	public void operation();
}


이제 이를 상속해서 실제 Leaf노드를 만들어 보자. Leaf노드에는 막다른 골목이기 때문에 그다지 많은 메서드를 넣어줄 필요가 없다. 그저 동작만을 뜻하는 operation() 메서드를 하나 만들어준다.

 

Leaf

public class Leaf implements Component{

	@Override
	public void operation() {
		System.out.println("막다른 부품입니다.");
	}

}


마지막으로 뭔가를 낑굴수 있는 확장가능한 Composite을 만들어보자.

 

Composite

public class Composite implements Component {
	
	ArrayList list = new ArrayList<>();
	
	public void add(Component c) {
		list.add(c);
	}
	
	public void remove(Component c) {
		list.remove(c);
	}
	
	public ArrayList getChild() {
		return list;
	}
	
	@Override
	public void operation() {
		for(Component c : list) c.operation();
	}

}

Composite은 상속받은 operation() 메서드 말고도 굳이 필요한 메서드가 하나있다. add()메서드이다. 이 메서드를 통해 다른 부품을 낑굴수 있다. 그것이 또다른 Composite이든, Leaf이든 막 낑굴수 있어야한다. 따라서 오버라이드되는 메서드는 operation() 하나만 존재하지만 추가적으로 구현해야하는 것들은 메서드로는 add(), 그리고 내부적으로 가지고있어야할 자식 부품에 대한 list 변수이다.


이제 마지막으로 테스트 메인을 만들어본다.

 

Main

public class Main {
	public static void main(String[] args) {
		
		Composite c1 = new Composite();
		Composite c2 = new Composite();
		Leaf l1 = new Leaf();
		Leaf l2 = new Leaf();
		
		c1.add(l1);
		c1.add(l2);
		c2.add(c1);
		
		c2.operation();
		
	}
}


Composite이 내부적으로 하나의 Composite을 부품으로 가지고 있으며 그 Composite부품은 내부에 Leaf부품을 두가지 가지고 있다. 결과적으로 c2.operation() 메서드를 콜하면, 자식들이 가지고 있는 operation() 메서드들이 작동이 되는 형식이다. Composite은 Leaf와 달리 다른 Component 들을 가지고 있는 list가 있기 때문이다. UML에서 대표적으로 튀어나오는 composite 형태의 화살표도 바로 이러한 것과 근본적으로 다르지 않을것이다.