컴포지트 패턴

컴포지트 패턴(Composite pattern)이란 객체들의 관계를 트리 구조로 구성하여 부분-전체 계층을 표현하는 패턴으로, 사용자가 단일 객체와 복합 객체 모두 동일하게 다루도록 한다.

구조

예

자바 
import java.util.List;
import java.util.ArrayList;

/** "Component" */
interface Graphic {

    //Prints the graphic.
    public void print();

}

/** "Composite" */
class CompositeGraphic implements Graphic {

    //Collection of child graphics.
    private List<Graphic> mChildGraphics = new ArrayList<Graphic>();

    //Prints the graphic.
    public void print() {
        for (Graphic graphic : mChildGraphics) {
            graphic.print();
        }
    }

    //Adds the graphic to the composition.
    public void add(Graphic graphic) {
        mChildGraphics.add(graphic);
    }

    //Removes the graphic from the composition.
    public void remove(Graphic graphic) {
        mChildGraphics.remove(graphic);
    }

}

/** "Leaf" */
class Ellipse implements Graphic {

    //Prints the graphic.
    public void print() {
        System.out.println("Ellipse");
    }

}

/** Client */
public class Program {

    public static void main(String[] args) {
        //Initialize four ellipses
        Ellipse ellipse1 = new Ellipse();
        Ellipse ellipse2 = new Ellipse();
        Ellipse ellipse3 = new Ellipse();
        Ellipse ellipse4 = new Ellipse();

        //Initialize three composite graphics
        CompositeGraphic graphic = new CompositeGraphic();
        CompositeGraphic graphic1 = new CompositeGraphic();
        CompositeGraphic graphic2 = new CompositeGraphic();

        //Composes the graphics
        graphic1.add(ellipse1);
        graphic1.add(ellipse2);
        graphic1.add(ellipse3);

        graphic2.add(ellipse4);

        graphic.add(graphic1);
        graphic.add(graphic2);

        //Prints the complete graphic (four times the string "Ellipse").
        graphic.print();
    }
}

C++ 

#include <iostream>
#include <vector>
#include <string>

using std::cout;
using std::vector;
using std::string;

class Component
{
  public:
   virtual void list() const = 0;
   virtual ~Component(){};
};

class Leaf : public Component
{
  public:
   explicit Leaf(int val) : value_(val)
   {
   }
   void list() const
   {
      cout << "   " << value_ << "\n";
   }
  private:
   int value_;
};

class Composite : public Component
{
  public:
   explicit Composite(string id) : id_(id)
   {
   }
   void add(Component *obj)
   {
      table_.push_back(obj);
   }
   void list() const
   {
      cout << id_ << ":" << "\n";
      for (vector<Component*>::const_iterator it = table_.begin();
       it != table_.end(); ++it)
      {
         (*it)->list();
      }
   }
  private:
   vector <Component*> table_;
   string id_;
};

int main()
{
   Leaf num0(0);
   Leaf num1(1);
   Leaf num2(2);
   Leaf num3(3);
   Leaf num4(4);
   Composite container1("Container 1");
   Composite container2("Container 2");

   container1.add(&num0);
   container1.add(&num1);

   container2.add(&num2);
   container2.add(&num3);
   container2.add(&num4);

   container1.add(&container2);
   container1.list();
   return 0;
}

Python3 
from abc import abstractmethod

class Component:
    @abstractmethod
    def my_list(self):
        pass

class Leaf(Component):
    val = None
    
    def __init__(self, val) -> None:
        super().__init__()
        self.val = val
    
    def my_list(self):
        print(self.val)

class Composite(Component):
    val = None
    composite_list = None

    def __init__(self, val) -> None:
        super().__init__()
        self.val = val
    
    def add(self, obj):
        if not self.composite_list:
            self.composite_list = []
        self.composite_list.append(obj)

    def my_list(self):
        print(self.val, ":")
        for obj in self.composite_list:
            obj.my_list()
        
def main():
    num0 = Leaf(0)
    num1 = Leaf(1)
    num2 = Leaf(2)
    num3 = Leaf(3)
    num4 = Leaf(4)

    container1 = Composite("Container 1")
    container2 = Composite("Container 2")

    container1.add(num0)
    container1.add(num1)

    container2.add(num2)
    container2.add(num3)
    container2.add(num4)

    container1.add(container2)
    container1.my_list()

if __name__ == "__main__":
    main()

소프트웨어 디자인 패턴