0

0

树状的组合模式(composite pattern)

巴扎黑

巴扎黑

发布时间:2016-11-12 14:08:45

|

1775人浏览过

|

来源于php中文网

原创

一个公司是由每一个工作的成员组成,每一个成员有不同的属性(名字,职位,薪水),根据不同的等级,构成一个树形的结构。总经理是这个棵树的根节点,因为他没有上级,部门经理是树枝节点,因为他既有上级也有下级,小喽啰是叶节点,因为他是最底层的苦逼,没有下级。现用组合模式将这个树展示出来,类图:

44bd3f10-f6ef-303e-8409-e99be2eefd1d.png

代码如下:

name = $name;
$this->position = $position;
$this->salary = $salary;
}
public function getInfo() {
$return = "姓名:".$this->name."\t";
$return .= "职位:".$this->position."\t";
$return .= "薪水:".$this->salary."\n";
return $return;
}
}
class Leaf extends Corp{
}
class Branch extends Corp{
private $subordinateList = array();
public function addSubordinate(Corp $corp){
array_push($this->subordinateList, $corp);
}
public function getSubordinateList(){
return $this->subordinateList;
}
}
$root = new Branch('马总','总经理',100000);
$branch1 = new Branch('罗总','研发部门经理',20000);
$branch2 = new Branch('高总','销售部门经理',80000);
$leaf1 = new Leaf('张三','开发人员',7000);
$leaf2 = new Leaf('李四','开发人员',8000);
$leaf3 = new Leaf('二蛋','销售人员',10000);
$leaf4 = new Leaf('狗子','销售人员',15000);
$root->addSubordinate($branch1);
$branch1->addSubordinate($leaf1);
$branch1->addSubordinate($leaf2);
$root->addSubordinate($branch2);
$branch2->addSubordinate($leaf3);
$branch2->addSubordinate($leaf4);
function getTreeInfo($branch){
echo $branch->getInfo();
$subordinateList = $branch->getSubordinateList();
foreach ($subordinateList as $value) {
if($value instanceof Branch){
getTreeInfo($value);
}else{
echo $value->getInfo();
}
}
}
getTreeInfo($root);
?>

运行结果:

姓名:马总 职位:总经理 薪水:100000

姓名:罗总 职位:研发部门经理 薪水:20000

姓名:张三 职位:开发人员 薪水:7000

姓名:李四 职位:开发人员 薪水:8000

姓名:高总 职位:销售部门经理 薪水:80000

姓名:二蛋 职位:销售人员 薪水:10000

姓名:狗子 职位:销售人员 薪水:15000

[Finished in 0.1s]

组合模式的定义

组合模式也叫合成模式,也叫部分-整体模式,主要是用来描述部分与整体的关系。其定义为:将对象组合成树形结构以表示”部分-整体“的层次结构,使得用户对单个对象和组合对象的使用具有一致性。组合模式主要由三个角色构成

1、Component抽象构件角色

定义参加组合对象的共有方法和属性,可以定义一些默认的行为或属性,比如例子中的Corp类。

2、Leaf叶子构件

3、Composite树枝构件

组合树枝节点和叶子节点形成一个树形结构

组合模式的优点

1、高层模块调用简单

一棵树形机构中的所有节点都是Component,局部和整体对调用者来说没有任何区别,也就是说,高层模块不必关心自己处理的是单个对象还是整个组合结构,简化了高层模块的代码。

2、节点自己增加

只要找到它的父节点就成,非常容易扩展,符合开闭原则。

植树节主题元素合集矢量模板
植树节主题元素合集矢量模板

植树节主题元素合集矢量模板适用于植树节活动宣传、环保组织的宣传材料、学校环境教育活动、春季主题活动海报、户外用品品牌的广告、自然保护项目的介绍、生态旅游的宣传册等与环境保护和自然教育相关设计的AI格式素材。

下载

组合模式的缺点

组合模式有一个非常明显的缺点,看到在场景类中的定义,提到树叶和树枝使用时的定义了吗?直接使用了实现类!这在面向接口编程上是很不恰当的,与依赖代表团原则冲突,限制了接口中的影响范围。

组合模式的使用场景

1、维护和展示部分-整体关系的场景,如树形菜单、文件、文件夹管理。

2、从一个整体中的能够独立出总价模块或功能的场景。 

组合模式的注意事项

只要是树形结构,就要考虑使用组合模式,这个一定要记住,只要是要体现局部和整体的关系的时候,而且这种关系还可能比较深,就应该考虑一下组合模式。

组合模式的扩展

1、真实的组合模式(略过)

2、透明的组合模式

例子中是安全的组合模式,透明模式是把用来组合的方法放到抽象类中(略过)

3、组合模式的遍历

例子中实现了树的从上级向下级遍历,如果现随便选中一个叶节点,如何向上级做遍历?

fe37e0d4-02dd-397b-ac87-9eaad5a79265.png

 其实也很简单,只要在添加节点时设置其父节点既可,代码如下:

private $parent = null;
public function __construct( $name, $position, $salary ) {
$this->name = $name;
$this->position = $position;
$this->salary = $salary;
}
public function getInfo() {
$return = "姓名:".$this->name."\t";
$return .= "职位:".$this->position."\t";
$return .= "薪水:".$this->salary."\n";
return $return;
}
public function setParent($parent){
$this->parent = $parent;
}
public function getParent(){
return $this->parent;
}
}
class Leaf extends Corp{
}
class Branch extends Corp{
private $subordinateList = array();
public function addSubordinate(Corp $corp){
$corp->setParent($this);
array_push($this->subordinateList, $corp);
}
public function getSubordinateList(){
return $this->subordinateList;
}
}
$root = new Branch('马总','总经理',100000);
$branch1 = new Branch('罗总','研发部门经理',20000);
$branch2 = new Branch('高总','销售部门经理',80000);
$leaf1 = new Leaf('张三','开发人员',7000);
$leaf2 = new Leaf('李四','开发人员',8000);
$leaf3 = new Leaf('二蛋','销售人员',10000);
$leaf4 = new Leaf('狗子','销售人员',15000);
$root->addSubordinate($branch1);
$branch1->addSubordinate($leaf1);
$branch1->addSubordinate($leaf2);
$root->addSubordinate($branch2);
$branch2->addSubordinate($leaf3);
$branch2->addSubordinate($leaf4);
function getParentInfo($leaf){
echo $leaf->getInfo();
$parent = $leaf->getParent();
if($parent instanceof branch)
getParentInfo($parent);
}
getParentInfo($leaf4);
?>

运行结果:

姓名:狗子 职位:销售人员 薪水:15000

姓名:高总 职位:销售部门经理 薪水:80000

姓名:马总 职位:总经理 薪水:100000

[Finished in 0.2s]

 代码中黑体部分为与上一例的区别。

相关专题

更多
php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

7

2025.12.31

php网站源码教程大全
php网站源码教程大全

本专题整合了php网站源码相关教程,阅读专题下面的文章了解更多详细内容。

4

2025.12.31

视频文件格式
视频文件格式

本专题整合了视频文件格式相关内容,阅读专题下面的文章了解更多详细内容。

7

2025.12.31

不受国内限制的浏览器大全
不受国内限制的浏览器大全

想找真正自由、无限制的上网体验?本合集精选2025年最开放、隐私强、访问无阻的浏览器App,涵盖Tor、Brave、Via、X浏览器、Mullvad等高自由度工具。支持自定义搜索引擎、广告拦截、隐身模式及全球网站无障碍访问,部分更具备防追踪、去谷歌化、双内核切换等高级功能。无论日常浏览、隐私保护还是突破地域限制,总有一款适合你!

7

2025.12.31

出现404解决方法大全
出现404解决方法大全

本专题整合了404错误解决方法大全,阅读专题下面的文章了解更多详细内容。

42

2025.12.31

html5怎么播放视频
html5怎么播放视频

想让网页流畅播放视频?本合集详解HTML5视频播放核心方法!涵盖<video>标签基础用法、多格式兼容(MP4/WebM/OGV)、自定义播放控件、响应式适配及常见浏览器兼容问题解决方案。无需插件,纯前端实现高清视频嵌入,助你快速打造现代化网页视频体验。

4

2025.12.31

关闭win10系统自动更新教程大全
关闭win10系统自动更新教程大全

本专题整合了关闭win10系统自动更新教程大全,阅读专题下面的文章了解更多详细内容。

3

2025.12.31

阻止电脑自动安装软件教程
阻止电脑自动安装软件教程

本专题整合了阻止电脑自动安装软件教程,阅读专题下面的文章了解更多详细教程。

3

2025.12.31

html5怎么使用
html5怎么使用

想快速上手HTML5开发?本合集为你整理最实用的HTML5使用指南!涵盖HTML5基础语法、主流框架(如Bootstrap、Vue、React)集成方法,以及无需安装、直接在线编辑运行的平台推荐(如CodePen、JSFiddle)。无论你是新手还是进阶开发者,都能轻松掌握HTML5网页制作、响应式布局与交互功能开发,零配置开启高效前端编程之旅!

2

2025.12.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PHP课程
PHP课程

共137课时 | 8.1万人学习

JavaScript ES5基础线上课程教学
JavaScript ES5基础线上课程教学

共6课时 | 6.9万人学习

PHP新手语法线上课程教学
PHP新手语法线上课程教学

共13课时 | 0.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号