合成模式

在软件工程中，合成模式（），也翻译为组成模式，是一种设计模式。合成模式描述了一组对象，按照对待相同对象类型的一个单一实例的方式处置它们。合成模式的意图是将诸多对象合成（compose）入表示部份-整体层级的树结构之中。实现合成模式使得客户能统一的处置单独对象和合成对象。

结构

在上面的UML类图中：
客户Client类不直接（单独的）提及Leaf和Composite类，Client转而提及公共的构件Component接口，并且统一的处置Leaf和Composite。
叶子Leaf类没有子对象并且直接实现Component接口。
合成Composite类维护Component对象（children）的一个容器，并且将请求转发到这些children（for each child in children: child.operation()）。

对象图展示运行时交互：在这个例子中，客户Client对象发送请求到树结构的顶层合成Composite对象（具有类型 Component) 。这个请求被沿着树结构转发到（办理于）所有的子Component对象（Leaf和Composite对象)。

 示例 
C++
下面的例子是基于《设计模式》书中先于C++98的样例代码的C++23实现。

import std;

using std::runtime_error;
using std::shared_ptr;
using std::string;
using std::unique_ptr;
using std::vector;

// Component object
// declares the interface for objects in the composition.
class Equipment {
private:
    string name;
    double netPrice;
protected:
    Equipment() = default;

    explicit Equipment(const string& name): 
        name{name}, netPrice{0} {}
public:
    // implements default behavior for the interface common to all classes, as appropriate.
    [[nodiscard]]
    virtual const string& getName() const noexcept {
        return name;
    }

    virtual void setName(const string& name) noexcept {
        this->name = name;
    }

    [[nodiscard]]
    virtual double getNetPrice() const noexcept {
        return netPrice;
    }

    virtual void setNetPrice(double netPrice) noexcept {
        this->netPrice = netPrice;
    }

    // declares an interface for accessing and managing its child components.
    virtual void add(shared_ptr<Equipment>) = 0;
    virtual void remove(shared_ptr<Equipment>) = 0;
    virtual ~Equipment() = default;
};

// Composite object
// defines behavior for components having children.
class CompositeEquipment: public Equipment {
private:
    // stores child components.
    using EquipmentList = vector<shared_ptr<Equipment>>;
    EquipmentList equipments;
protected:
    CompositeEquipment() = default;

    explicit CompositeEquipment(const string& name):
        Equipment(name), equipments{EquipmentList()} {}
public:
    // implements child-related operations in the Component interface.
    [[nodiscard]]
    virtual double getNetPrice() const noexcept override {
        double total = Equipment::getNetPrice();
        for (const Equipment& i: equipments) {
            total += i->getNetPrice();
        }
        return total;
    }

    virtual void add(shared_ptr<Equipment> equipment) override {
        equipments.push_back(equipment.get());
    }

    virtual void remove(shared_ptr<Equipment> equipment) override {
        equipments.remove(equipment.get());
    }
};

// Leaf object
// represents leaf objects in the composition.
class FloppyDisk: public Equipment {
public:
    explicit FloppyDisk(const String& name):
        Equipment(name) {}

    // A leaf has no children.
    void add(shared_ptr<Equipment>) override {
        throw runtime_error("FloppyDisk::add() cannot be called!");
    }

    void remove(shared_ptr<Equipment>) override {
        throw runtime_error("FloppyDisk::remove() cannot be called!");
    }
};

class Chassis: public CompositeEquipment {
public:
    explicit Chassis(const string& name): 
        CompositeEquipment(name) {}
};

int main() {
    shared_ptr<FloppyDisk> fd1 = std::make_shared<FloppyDisk>("3.5in Floppy");
    fd1->setNetPrice(19.99);
    std::println("{}: netPrice = {}", fd1->getName(), fd1->getNetPrice);

    shared_ptr<FloppyDisk> fd2 = std::make_shared<FloppyDisk>("5.25in Floppy");
    fd2->setNetPrice(29.99);
    std::println("{}: netPrice = {}", fd2->getName(), fd2->getNetPrice);

    unique_ptr<Chassis> ch = std::make_unique<Chassis>("PC Chassis");
    ch->setNetPrice(39.99);
    ch->add(fd1);
    ch->add(fd2);
    std::println("{}: netPrice = {}", ch->getName(), ch->getNetPrice);

    fd2->add(fd1);
}

程序的输出为：

3.5in Floppy: netPrice=19.99
5.25in Floppy: netPrice=29.99
PC Chassis: netPrice=89.97
terminate called after throwing an instance of 'std::runtime_error'
  what():  FloppyDisk::add

Python
下面是Python的例子：
from abc import ABC, abstractmethod

class Component(ABC):
    def __init__(self, name, price=0, **kwargs):
        self.name = name
        self.price = price
        for key, value in kwargs.items():
            self.__dict__[key] = value
    def get_name(self):
        return self.name
    def set_price(self, price):
        self.price = price
    def get_price(self):
        return self.price
    @abstractmethod
    def get_price(self): pass

class Leaf(Component):
    def get_price(self):
        return self.price

class Composite(Component):
    def __init__(self, *args, **kwargs):
        self.linked_list = []
        super().__init__(*args, **kwargs)
    def __len__(self):
        return len(self.linked_list)
    def __getitem__(self, index):
        return self.linked_list[index]
    def __setitem__(self, index, value):
        self.linked_list[index] = value
    def __delitem__(self, index):
        del self.linked_list[index]
    def add(self, equipment):
        self.linked_list.insert(0, equipment)
    def remove(self, equipment):
        self.linked_list.remove(equipment)
    def get_price(self):
        total = self.price
        for i in self.linked_list:
            total += i.get_price()
        return total

class ComputerCase(Composite): pass

class Chassis(Leaf): pass

class Motherboard(Composite): pass

class CPU(Leaf): pass

class RAM(Leaf): pass

class HardDisk(Leaf): pass

def demo():
    pc = ComputerCase("an assembled computer")
    pc.add(Chassis("Full-tower", 50))
    pc.add(Motherboard("ATX board", 180))
    pc[0].add(CPU("x86-64 CPU", 200))
    pc[0].add(RAM("DDR4", 150))
    pc[0].add(HardDisk("SSD", 250))
    print(f"The price of {pc.get_name()} is {pc.get_price()}.")
其执行：
>>> demo()
The price of an assembled computer is 830.

参见
混入
享元模式
访问者模式

 引用 

 外部链接 

Composite Pattern  implementation in Java
Composite pattern description from the Portland Pattern Repository
Composite pattern in UML and in LePUS3, a formal modelling language
Class::Delegation on CPAN 
"The End of Inheritance: Automatic Run-time Interface Building for Aggregated Objects"  by Paul Baranowski
PerfectJPattern Open Source Project , Provides componentized implementation of the Composite Pattern in Java
 A persistent Java-based implementation
Composite Design Pattern 

Category:软件设计模式