Design pattern/구조 패턴

[디자인패턴] 9장 복합체 패턴

미스터로즈 2021. 5. 10. 21:36

공부하기 위해서 요약정리해놓은 것입니다..

 

정확하고 꼼꼼한 자료는 쉽게 배워 바로 써먹는 디자인 패턴을 확인하시고

코드는 github.com/infohojin/patterns 을 참고해 주세요.

 

복합체 패턴은 객체 간의 계층적 구조화를 통해 객체를 확장하는 패턴입니다. 복합체는 재귀적으로 결합된 계층화된 트리 구조의 객체입니다.

 

객체를 포함하는 객체

복합 객체는 객체가 또 다른 객체를 포함하는 것을 말합니다. 복합적인 객체 관계를 복합화 또는 집단화라고 합니다.

<?php

class Computer
{
    public $Monitor;
    public $name = "구성";

    public function setMonitor($monitor)
    {
        $this->Monitor = $monitor;
    }
}
<?php

class Monitor
{
    public $name = "모니터";
}
<?php
require "computer.php";
require "monitor.php";

// Client
$obj = new Computer;
$obj->setMonitor(new Monitor);

echo $obj->name."\n";
echo $obj->Monitor->name."\n";

Computer 클래스가 의존 관계인 Monitor 클래스를 가지고 있습니다.

이처럼 복합 객체는 하나의 객체가 다른 객체를 포함하는 구조입니다.

 

복합 객체의 특징은 다른 객체 정보를 포함하면서 수평적으로 확장된다는 것입니다. 즉, 객체는 여러 개의 객체 정보를 동시에 가질 수 있습니다.

<?php

class Computer
{
    public $Monitor;
    public $Disk;
    public $Memory;

    public $name = "구성";

    public function setMonitor($monitor)
    {
        $this->Monitor = $monitor;
    }

    public function setDisk($disk)
    {
        $this->Disk = $disk;
    }

    public function setMemory($momory)
    {
        $this->Memory = $momory;
    }
}

이 처럼 집단화된 객체는 부분 - 전체 계층 구조가 됩니다. 또한 객체들은 트리 구조형태의 계층화 구조를 가집니다.

 

수평으로 확장하는 것은 하나의 객체가 여러 객체를 포함하는 것을 말합니다. 즉, 자식이 하나씩만 존재합니다.

 

복합 객체를 자식 객체로 사용할 때는 수직적 확장 구조를 갖습니다. 복합 객체는 수직적 확장을 통해 계층적이고 복잡한 트리 구조를 갖게 됩니다.

 

복합체 패턴은 크게 4개의 구성요소로 이루어 집니다.

- Component

- Composite

- Leaf

- Client

 

복합체의 구성 요소인 Composite와 leaf는 엄밀히 다른 객체입니다. 복합체는 2개의 객체를 모두 관리하기 위해 동일한 Component 인터페이스를 적용하며, 인터페이스에는 두 객체의 공통된 기능이 모두 포함됩니다.

 

복합체 패턴은 Component 인터페이스를 이용하여 component 객체와 leaf 객체를 서로 구별하지 않고 동일한 동작으로 처리합니다.

추상화를 통한 일반화 작업

복합 객체를 복합체 패턴으로 재정의하는 목적은 재귀적으로 결합된 노드에 동일한 형태로 접근하기 위해서입니다.

일반화 작업은 인터페이스를 이용하는 방법과 추상화를 이용하는 방법이 있습니다.

복합체 패턴은 일반화를 위한 방법으로 추상 클래스를 사용합니다.

 

복합체는 계층적 트리구조로 되어 있습니다. 노드의 제일 마지막 객체를 리프라고 합니다.

 

리프는 트리 구조에서 제일 마지막에 존재하며 다른 객체를 포함할 수 없습니다. 하지만 마지막 객체는 리프 객체 말고 복합체 패턴으로도 사용될 수 있으며, 마지막 노드가 복합체 패턴일 경우 객체를 추가로 더 확장할 수 있습니다.

 

리프 객체도 공통된 인터페이스인 추상 클래스를 상속받아 동일한 접속과 처리를 진행합니다.

<?php
/**
 * 컴포넌트 추상화를 적용
 */
class Leaf extends Component
{
    private $price;

    public function __construct($name)
    {
        $this->setName($name);
    }

    public function getPrice()
    {
        return $this->price;
    }

    public function setPrice($price)
    {
        $this->price = $price;
    }
}

 

현재 객체가 마지막 리프일 경우 직접 행동을 수행하고, 객체가 복합체 패턴일 경우 자식 객체로 위임을 요청합니다. 위임할 때는 미리 정해둔 다른 사전 동작을 먼저 수행할 수도 있습니다.

 

장점

복합체 패턴으로 트리 구조를 구현하면 트리를 추가하거나 이동, 삭제하여 전체적인 구조를 유지하는 데 매우 유용합니다. 복합체 패턴에서 트리 구조의 재귀적인 특징을 잘 응용하는 것이라고 볼 수 있습니다.

 

복합체 패턴은 투명성을 이용해 클라이언트의 사용을 단순화할 수 있습니다. 

 

단점

복합체 패턴은 설계의 범용성이 뛰어납니다. 하지만 수평적 방향으로만 확장이 가능하도록 Leaf를 제한하는 Composite를 만들기는 어렵습니다.