GoF 디자인패턴 - Composite

Clean Code Big Poo·2025년 6월 3일
0
post-thumbnail

Overview

디자인패턴 시작하기를 보고 정리하기

Composite

단일체집합체를 하나의 동일한 개념으로 처리하기 위한 패턴

  • 구슬 : 단일체
  • 상자 : 집합체

위 그림은 총 4가지 상황을 의미함.
여러 상황을 1가지 개념으로 처리하여 상황을 단순화 함.

다이어그램

  • Unit : Folder 와 File을 동일한 개념(타입)으로 처리하기 위해 File과 Folder는 Unit을 상속한다.
  • File : 단일체
  • Folder : 집합체
    • Folder 안에는 다른 Folder 가 존재 할 수 있다.
    • Folder 는 여러개의 Unit을 가질 수 있다.
      • Folder 나 File을 여러개 가질 수 있다.

구현 코드

Unit

public abstract class Unit {
    private String name;

    public Unit(String name){
        this.name = name;
    }

    public String getName(){
        return name;
    }

    @Override
    public String toString(){
        return  name + "(" + getSize() + ")";
    }

    /// abstract 인 이유?
    /// 파일 / 폴더는 크기를 얻는 방법이 각각 다르기 떄문에
    public abstract int getSize();
}

File

public class File extends Unit{
    private int size;

    public File(String name, int size){
        super(name);

        this.size= size;
    }

    @Override
    public int getSize() {
        return size;
    }
}

Folder

import java.util.Iterator;
import java.util.LinkedList;

public class Folder extends Unit{
    private LinkedList<Unit> unitList = new LinkedList<Unit>();

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

    @Override
    public int getSize() {
        // 나의 하위의 모든 파일의 사이즈를 합하여 리턴
        int size = 0;
        Iterator<Unit> it = unitList.iterator();

        while (it.hasNext()){
            Unit unit = it.next();
            size += unit.getSize();
        }

        return size;
    }

    public boolean add(Unit unit){
        unitList.add(unit);

        return true;
    }

    private void list(String indent, Unit unit){
        if(unit instanceof File){
            System.out.println(indent + unit);
        }else {
            Folder dir = (Folder) unit;
            Iterator<Unit> it = dir.unitList.iterator();
            System.out.println(indent + "+ "+unit);
            while (it.hasNext()){
                list(indent + "   ", it.next());
            }
        }
    }

    /// private list 를 호출하는 구조
    /// 자기자신을 다시 호출하는 재귀 구문
    /// 단일체와 집합체를 동일한 선상에서 처리하다보니, 재귀 구문이 필요한 경우가 많음.
    public void list(){
        list("", this);
    }
}

Main


import java.util.ArrayList;

public class Main {
    public static void main(String[] args){
        Folder root = new Folder("root");
        root.add(new File("a.txt", 1000));
        root.add(new File("b.txt", 2000));

        Folder sub1 = new Folder("sub1");
        root.add(sub1);
        sub1.add(new File("sa.txt", 100));
        sub1.add(new File("sb.txt", 200));

        Folder sub2 = new Folder("sub2");
        root.add(sub2);
        sub2.add(new File("s2a.txt", 100));
        sub2.add(new File("s2b.txt", 200));

        root.list();
    }
}

0개의 댓글