[toc]
## 举个例子
> 网上买配件, 自己攒电脑
> 简单组合, 即可使用, 没有显卡, 照样能用
## 代码示例
```php
<?php
// 组件,所有子配件的基类
class Component {
protected $name;
public function __construct($name) {
$this->name = $name;
}
public function showInfo($indent = "") {
}
public function isComposite() {
return false;
}
public function startup($indent = "") {
echo $indent . $this->name . " 准备开始工作..." . PHP_EOL;
}
public function shutdown($indent = "") {
echo $indent . $this->name . " 即将结束工作..." . PHP_EOL;
}
}
// 中央处理器
class CPU extends Component {
public function __construct($name) {
parent::__construct($name);
}
public function showInfo($indent = '') {
echo $indent;
echo "CPU: " . $this->name . ",可以进行高速计算。" . PHP_EOL;
}
}
// 内存条
class MemoryCard extends Component {
public function __construct($name) {
parent::__construct($name);
}
public function showInfo($indent = '') {
echo $indent;
echo "内存: " . $this->name . ",可以缓存数据,读写速度快。" . PHP_EOL;
}
}
// 硬盘
class HardDisk extends Component {
public function __construct($name) {
parent::__construct($name);
}
public function showInfo($indent = '') {
echo $indent;
echo "硬盘: " . $this->name . ",可以永久存储数据,容量大。" . PHP_EOL;
}
}
// 显卡
class GraphicsCard extends Component {
public function __construct($name) {
parent::__construct($name);
}
public function showInfo($indent = '') {
echo $indent;
echo "显卡: " . $this->name . ",可以高速计算和处理图形图像。" . PHP_EOL;
}
}
// 电源
class Battery extends Component {
public function __construct($name) {
parent::__construct($name);
}
public function showInfo($indent = '') {
echo $indent;
echo "电源: " . $this->name . ",可以持续给主板和外接配件供电。" . PHP_EOL;
}
}
// 风扇
class Fan extends Component {
public function __construct($name) {
parent::__construct($name);
}
public function showInfo($indent = '') {
echo $indent;
echo "风扇: " . $this->name . ",辅助CPU散热。" . PHP_EOL;
}
}
// 显示器
class Displayer extends Component {
public function __construct($name) {
parent::__construct($name);
}
public function showInfo($indent = '') {
echo $indent;
echo "显示器:" . $this->name . ",负责内容的显示。" . PHP_EOL;
}
}
// 配件组合器
class Composite extends Component {
protected $components;
public function __construct($name) {
parent::__construct($name);
$this->components = [];
}
public function showInfo($indent = '') {
echo $this->name . ",由以下部件组成:" . PHP_EOL;
$indent .= "\t";
foreach ($this->components as $element) {
$element->showInfo($indent);
}
}
public function isComposite() {
return True;
}
public function addComponent($component) {
array_push($this->components, $component);
}
public function removeComponent($component) {
$this->components = array_merge(array_diff($this->components, array($component)));
}
public function startup($indent = '') {
parent::startup($indent);
$indent .= "\t";
foreach ($this->components as $element) {
$element->startup($indent);
}
}
public function shutdown($indent = '') {
parent::startup($indent);
$indent .= "\t";
foreach ($this->components as $element) {
$element->shutdown($indent);
}
}
}
// 主板
class Mainboard extends Composite {
public function __construct($name) {
parent::__construct($name);
}
public function showInfo($indent = '') {
echo $indent . "主板: ";
parent::showInfo($indent);
}
}
// 机箱
class ComputerCase extends Composite {
public function __construct($name) {
parent::__construct($name);
}
public function showInfo($indent = '') {
echo $indent . "机箱: ";
parent::showInfo($indent);
}
}
// 电脑
class Computer extends Composite {
public function __construct($name) {
parent::__construct($name);
}
public function showInfo($indent = '') {
echo $indent . "电脑: ";
parent::showInfo($indent);
}
}
//测试代码
$cpu = new CPU("Intel Core i5-6600K");
$memoryCard = new MemoryCard("Kingston Fury DDR4");
$hardDisk = new HardDisk("Kingston V300 ");
$graphicsCard = new GraphicsCard("Colorful iGame750");
$mainBoard = new Mainboard("GIGABYTE Z170M M-ATX");
$mainBoard->addComponent($cpu);
$mainBoard->addComponent($memoryCard);
$mainBoard->addComponent($hardDisk);
$mainBoard->addComponent($graphicsCard);
$battery = new Battery("Antec VP 450P");
$fan = new Fan("DEEPCOOL 120T");
$computerCase = new ComputerCase("SAMA MATX");
$computerCase->addComponent($battery);
$computerCase->addComponent($mainBoard);
$computerCase->addComponent($fan);
$displayer = new Displayer("AOC LV243XIP");
$computer = new Computer("Tony DIY电脑");
$computer->addComponent($displayer);
$computer->addComponent($computerCase);
$computer->showInfo("");
echo "\n开机过程:";
$computer->startup("");
echo "\n关机过程:";
$computer->shutdown("");
```
```
D:\soft\php72\php.exe D:\project\php_dp\index2.php
电脑: Tony DIY电脑,由以下部件组成:
显示器:AOC LV243XIP,负责内容的显示。
机箱: SAMA MATX,由以下部件组成:
电源: Antec VP 450P,可以持续给主板和外接配件供电。
主板: GIGABYTE Z170M M-ATX,由以下部件组成:
CPU: Intel Core i5-6600K,可以进行高速计算。
内存: Kingston Fury DDR4,可以缓存数据,读写速度快。
硬盘: Kingston V300 ,可以永久存储数据,容量大。
显卡: Colorful iGame750,可以高速计算和处理图形图像。
风扇: DEEPCOOL 120T,辅助CPU散热。
开机过程:Tony DIY电脑 准备开始工作...
AOC LV243XIP 准备开始工作...
SAMA MATX 准备开始工作...
Antec VP 450P 准备开始工作...
GIGABYTE Z170M M-ATX 准备开始工作...
Intel Core i5-6600K 准备开始工作...
Kingston Fury DDR4 准备开始工作...
Kingston V300 准备开始工作...
Colorful iGame750 准备开始工作...
DEEPCOOL 120T 准备开始工作...
关机过程:Tony DIY电脑 准备开始工作...
AOC LV243XIP 即将结束工作...
SAMA MATX 准备开始工作...
Antec VP 450P 即将结束工作...
GIGABYTE Z170M M-ATX 准备开始工作...
Intel Core i5-6600K 即将结束工作...
Kingston Fury DDR4 即将结束工作...
Kingston V300 即将结束工作...
Colorful iGame750 即将结束工作...
DEEPCOOL 120T 即将结束工作...
Process finished with exit code 0
```
## 代码说明
1. 组装的电脑是由各个配件组成的,在组装之前,就是一个个 CPU、硬盘、显卡等配件,不能称之为电脑
2. 只有把它们按正确的方式组装在一起,配合操作系统才能正常运行。
3. 一般人使用电脑并不会关注内部的组成结构,只会关注一台整机。
4. 这里有明显的部分与整体的关系,主板、电源等是电脑的一部分,而主板上又有 CPU、硬盘、显卡,它们又可以认为是主板的一部分。
## 什么是组合模式?
> 像电脑一样,把对象组合成树形结构,以表示“部分-整体”的层次结构的程序设计模式就叫组合模式。
> 组合模式使得用户对单个对象和组合对象的使用具有一致性,使用组合对象就像使用单个对象一样,不用关心内部的组织结构。
> 组合模式是一个非常常用的模式,你可能在有意或无意间就已经用上了,比如公司(各个部门或各个子公司)的组织架构,学校各个学院-班级的关系
![](https://box.kancloud.cn/8674b9c50965e920ff1f353dea0ee9cb_741x258.png)
![](https://box.kancloud.cn/55bdfd171d4f1b05aa18a61bbfa3ea63_734x394.png)
## 优缺点
**组合模式的优点**
1. 调用简单,组合对象可以像一般对象一样使用。
1. 组合对象可以自由地增加、删除组件,可灵活地组合不同的对象。
**组合模式的缺点**
1. 在一些层次结构太深的场景中,组合结构会变得太庞杂(本质是树形结构)。
## 应用场景
1. 对象之间具有明显的“部分-整体”的关系时,或者具有层次关系时。
1. 组合对象与单个对象具有相同或类似行为(方法),用户希望统一地使用组合结构中的所有对象。