合成模式

在软件工程中，合成模式，也翻译为组成模式，是一种设计模式。合成（composite）模式描述了一组对象，按照对待相同对象类型的一个单一实例的方式处置它们。合成模式的意图是将诸多对象合成（compose）入表示部份-整体层级的树结构之中。实现合成模式使得客户能统一的处置单独对象和合成对象。
结构.
在上面的UML类图中：
对象图展示运行时交互：在这个例子中，客户codice_1对象发送请求到树结构的顶层合成codice_3对象（具有类型 codice_5) 。这个请求被沿着树结构转发到（办理于）所有的子codice_5对象（codice_2和codice_3对象)。
示例.
C++.
下面的例子是基于《设计模式》书中先于C++98的样例代码的C++23实现。
import std;
using Currency = double;
template &lt;typename T&gt;
using LinkedList = std::list&lt;T&gt;;
// declares the interface for objects in the composition.
class Equipment { // Component
private:
 std::string name;
 Currency netPrice;
protected:
 Equipment() = default;
 Equipment(const String&amp; name): 
public:
 // implements default behavior for the interface common to all classes, as appropriate.
 nodiscard
 virtual const std::string&amp; getName() const noexcept {
 return name;
 virtual void setName(const std::string&amp; name_) noexcept {
 name = name_;
 nodiscard
 virtual Currency getNetPrice() const noexcept {
 return netPrice;
 virtual void setNetPrice(Currency netPrice_) noexcept {
 netPrice = netPrice_;
 // declares an interface for accessing and managing its child components.
 virtual void add(std::shared_ptr&lt;Equipment&gt;) = 0;
 virtual void remove(std::shared_ptr&lt;Equipment&gt;) = 0;
 virtual ~Equipment() = default;
// defines behavior for components having children.
class CompositeEquipment : public Equipment { // Composite
private:
 // stores child components.
 LinkedList&lt;std::shared_ptr&lt;Equipment» equipment;
protected:
 CompositeEquipment() = default;
 CompositeEquipment(const std::string&amp; name):
public:
 // implements child-related operations in the Component interface.
 nodiscard
 virtual Currency getNetPrice() const noexcept override {
 Currency total = Equipment::getNetPrice();
 for (const Equipment&amp; i: equipment) {
 total += i-&gt;getNetPrice();
 return total;
 virtual void add(std::shared_ptr&lt;Equipment&gt; equipment_) override {
 equipment.push_front(equipment_.get());
 virtual void remove(std::shared_ptr&lt;Equipment&gt; equipment_) override {
 equipment.remove(equipment_.get());
};
// represents leaf objects in the composition.
class FloppyDisk : public Equipment { // Leaf
public:
 FloppyDisk(const std::string&amp; name_):
 // A leaf has no children.
 void add(std::shared_ptr&lt;Equipment&gt;) override {
 throw std::runtime_error("FloppyDisk::add() cannot be called!");
 void remove(std::shared_ptr&lt;Equipment&gt;) override {
 throw std::runtime_error("FloppyDisk::remove() cannot be called!");
};
class Chassis : public CompositeEquipment {
public:
 Chassis(const std::string&amp; name): 
int main() {
 // The smart pointers prevent memory leaks.
 std::shared_ptr&lt;FloppyDisk&gt; fd1 = std::make_shared&lt;FloppyDisk&gt;("3.5in Floppy");
 fd1-&gt;setNetPrice(19.99);
 std::println("{}: netPrice = {}", fd1-&gt;getName(), fd1-&gt;getNetPrice);
 std::shared_ptr&lt;FloppyDisk&gt; fd2 = std::make_shared&lt;FloppyDisk&gt;("5.25in Floppy");
 fd2-&gt;setNetPrice(29.99);
 std::println("{}: netPrice = {}", fd2-&gt;getName(), fd2-&gt;getNetPrice);
 std::unique_ptr&lt;Chassis&gt; ch = std::make_unique&lt;Chassis&gt;("PC Chassis");
 ch-&gt;setNetPrice(39.99);
 ch-&gt;add(fd1);
 ch-&gt;add(fd2);
 std::println("{}: netPrice = {}", ch-&gt;getName(), ch-&gt;getNetPrice);
 fd2-&gt;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 Equipment(ABC):
 def __init__(self, name, netprice=None, **kwargs):
 self.name = name
 self.netprice = netprice
 for key, value in kwargs.items():
 self.__dict__[key] = value
 def get_name(self):
 return self.name
 def set_netprice(self, netprice):
 self.netprice = netprice
 def get_netprice(self):
 return self.netprice
 @abstractmethod
 def get_netprice(self): pass
class LeafEquipment(Equipment):
 def get_netprice(self):
 return self.netprice
class CompositeEquipment(Equipment):
 def __init__(self, *args, **kwargs):
 self.linked_list = []
 super().__init__(*args, **kwargs)
 def add(self, equipment):
 self.linked_list.insert(0, equipment)
 def remove(self, equipment):
 self.linked_list.remove(equipment)
 def get_netprice(self):
 total = (0 if self.netprice is None
 else self.netprice)
 for i in self.linked_list:
 total += i.get_netprice()
 return total
class ComputerCase(CompositeEquipment): pass
class Chassis(LeafEquipment): pass
class Motherboard(CompositeEquipment): pass
class CPU(LeafEquipment): pass
class RAM(LeafEquipment): pass
class HardDisk(LeafEquipment): pass
def demo():
 cpu = CPU("x86-64 CPU", 200)
 ram = RAM("DDR4", 150)
 hd = HardDisk("SSD", 250)
 board = Motherboard("ATX board", 180)
 board.add(cpu)
 board.add(ram)
 board.add(hd)
 chassis = Chassis("Full-tower", 50)
 pc_case = ComputerCase("an assembled computer")
 pc_case.add(board)
 pc_case.add(chassis)
 print(f"The net price of {pc_case.get_name()} is {pc_case.get_netprice()}.")
其执行：
»&gt; demo()
The net price of an assembled computer is 830.