Notice
Recent Posts
Recent Comments
Link
«   2025/06   »
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
Archives
Today
Total
관리 메뉴

JAVA Developer Training

컴포지트 패턴 (Composite Pattern) 본문

디자인패턴

컴포지트 패턴 (Composite Pattern)

Romenest 2021. 9. 27. 12:56

복합체 패턴은 구조 패턴중 하나로 객체들의 관계를 Tree 구조로 구성하여 부분 - 전체 계층을 표현하는 패턴이다.

복합체 패턴은 복합 객체 그룹(전체)단일 객체를 동일하게 취급, 이용 할 수 있게해주는 방식이다

 

*Tree 구조

계층적인 구조를 표현하기 위해 일상적으로 사용하는 구조

대표적인 예로 회사의 조직도, 내 컴퓨터의 폴더 위치 ( C:\Program Files\.... ) 가 있겠다

 

복합체 패턴은 단일 개체와 복합개체를 같은 방법으로 사용할 수 있게 일반화 하여 클래스를 제공한다.

때문에 기반 클래스에서 단일,복합 개체에서 할 수 있는 모든 기능을 인터페이스로 약속한다는것이 중요하다.

모든 기능을 인터페이스로 구성 했기에 해당개체가 단일이던 복합이던 몰라도 같은방법으로 사용할 수 있다는게 

복합체 패턴의 특징이라 볼 수 있다.

 

하지만 이러한 복합체 패턴은 실제 사용되는 개체에 아무 필요 없는 기능까지 클래스에서 제공하기 때문에 리소스가 낭비 된다고 볼 수 있다. 

 

장점, 단점이 있는 복합체 패턴이지만 이를 사용해야하는지에 대한 판단이 어렵다면

컴퓨터의 폴더를 생각하자 폴더처럼 복합개체,단일개체를 동일하게 이용하고 싶은가? 

그렇다면 복합체 패턴을 사용해보자

 

실생활 예시를 들어 이해하기 쉽게 풀어보겠다

 

스마트폰을 사용한지 약 10년이 넘는 시간이 지났다. 그동안 내 스마트폰에는 수많은 사진들이 저장되었고

그중에는 친구들과 여행가서 찍은사진, 가족과 여행가서 찍은사진, 혼자 놀러가서 찍은사진 등등이 있겠다.

그런데 친구들과 찍은 사진으로 검색하니 여행을 한번만 간것도 아니고 여러장이 올라와 구별하기 힘들고

이걸 여행을 갔던 시기별로 검색을 하자니 친구들, 가족, 개인사진이 같이 올라와 찾기가 힘들다고 생각했다.

그렇다고 각각의 사진들을 각 카테고리별로 복사해서 추가하는건 너무 낭비같다고 생각하고

그래서 이번에 사진을 쉽게 찾아낼수 있는 기능을 만들어 보기로했다.

카테고리를 추가하고 각 카테고리에 하위카테고리를 만들고 사진이 있는 절대 경로를 보관할생각이다.

 

만들고자 하는 경로는 단일 개체가 되겠고 카테고리는 복합개체가 되겠다.

경로,카테고리를 같은 방식으로 사용할 수 있게 하기위해 모든 기능을 트리에서 제공할 것이다.

그리고 경로와 카테고리에서는 각자 자신이 해야할 기능에 대해 재정의를 해줄것이고

카테고리 개체는 복합 개체이므로 트리 형식의 개체를 소유할 수 있게 해줄것이다.

 

 

 

구현 

Tree

Tree클래스는 경로와 카테고리에 모든 기능을 제공하는 역할을 한다

public abstract class Tree {
    private String Name;

    public final String getName() {
        return Name;
    }

    private void setName(String value) {
        Name = value;
    }

    private Tree Parent;

    public final Tree getParent() {
        return Parent;
    }

    public final void setParent(Tree value) {
        Parent = value;
    }

    public abstract void View();

    public void AddChild(Tree child) {
        // 복합 개체에서만 필요한 기능
    }

    public void RemoveChild(Tree child) {
        // 복합 개체에서만 필요한 기능
    }

    public Tree(String name) {
        setName(name);
        setParent(null);
    }
}

 

Path (단일개체)

Path클래스는 자신의 정보를 보여주는 기능을 가진다

public class Path extends Tree {
    public Path(String path) {
        super(path);
    }

    @Override
    public void View() {
        System.out.printf("%1$s" + "\r\n", getName());
    }
}

Categori (복합개체)

Categori 클래스는 자신의 정보 및 자식요소들의 정보를 보여주는 기능을 가진다.

또한 Categori 클래스는 자식을 추가하거나 제거하는 기능을 가지고있어야한다.

하지만 단일개체인 Path클래스에는 추가할, 재정의할 기능이 없으므로 비워둔다.

여기서 복합체 패턴의 단점인 불필요한 기능까지 제공해준다는 점을 알 수 있다.

import java.util.*;

public class Category extends Tree {
    private ArrayList<Tree> children = new ArrayList<Tree>();

    public Category(String name) {
        super(name);
    }

    @Override
    public void View() {
        System.out.printf("%1$s-C" + "\r\n", getName());
        for (Tree child : children) {
            child.View();
        }
    }

    @Override
    public void AddChild(Tree child) // Category에만 필요한 기능
    {
        child.getParent() = this;
        children.add(child);
    }

    @Override
    public void RemoveChild(Tree child) // Category에만 필요한 기능
    {
        child.Parent = null;
        children.remove(child);
    }
}

 

 

예제코드

public class Program {
    public static void main(String[] args) {
        Tree tree = new Category("사진트리");
        Tree date_tree = MakeDemoDateTree();
        Tree location_tree = MakeDemoLocationTree();

        tree.AddChild(date_tree);
        tree.AddChild(location_tree);
        tree.View();
    }

    private static Tree MakeDemoLocationTree() {
        Tree tree = new Category("지역");
        Tree sub1 = new Category("제주");
        Tree sub2 = new Category("천안");
        Tree sub3 = new Category("서울");
        Tree sub4 = new Path("C:\\사진\\외도");
        Tree sub2_1 = new Path("C:\\사진\\현충사의봄");

        sub2.AddChild(sub2_1);
        tree.AddChild(sub1);
        tree.AddChild(sub2);
        tree.AddChild(sub3);
        tree.AddChild(sub4);
        return tree;
    }

    private static Tree MakeDemoDateTree() {
        Tree tree = new Category("날짜");
        Tree sub1 = new Category("20120429");
        Tree sub2 = new Category("20120407");
        Tree sub3 = new Category("20120507");

        Tree sub1_1 = new Path("C:\\사진\\외도");
        sub1.AddChild(sub1_1);
        Tree sub2_1 = new Path("C:\\사진\\현충사의봄");
        sub2.AddChild(sub2_1);
        Tree sub3_1 = new Path("C:\\사진\\일산고구마모종");
        sub3.AddChild(sub3_1);

        tree.AddChild(sub1);
        tree.AddChild(sub2);
        tree.AddChild(sub3);

        return tree;
    }
}

 

 

 

 

 

http://ehpub.co.kr/8-%eb%b3%b5%ed%95%a9%ec%b2%b4-%ed%8c%a8%ed%84%b4composite-pattern-%ea%b5%ac%ed%98%84/