设计模式 | 组合模式

简介: 设计模式 | 组合模式

说明

模式定义: 组合模式(Composite Pattern)有时候又叫做部分-整体模式,用于将对象组合成树形结构以表示“部分-整体”的层次关系。组合模式使得用户对单个对象和组合对象的使用具有一致性。

常见使用场景:如树形菜单、文件夹菜单、部门组织架构图等。

说到树形就需要先说说树的基本构成:

  • 根节点

是树的一个组成部分,也叫树根。它是同一棵树中除本身外所有结点的祖先,没有父结点。

  • 叶子结点

一棵树当中没有子结点(即度为0)的结点。 叶子是指度为0的结点,又称为终端结点。

  • 子树

子树就是树的其中一个节点以及其下面的所有的节点所构成的树

组合模式结构说明

在组合模式中有三个角色, ComponentLeafComposite, 我们分别看一下

  • Component

这是组合模式中对象声明的接口, 在适当情况下, 实现所有类共有的接口默认行为, 用于访问和管理Component部件, Component可以是抽象类或者接口。

  • Leaf

在组合中表示叶子结点, 叶子结点没有子节点

  • Composite

非叶子结点, 用于存储子部件, 在Component接口中实现子部件的相关操作, 比如增加

示例

编写程序展示一个学校的院系结构,需求: 要在一个页面中展示出学校的院系组成,一个学校有多个学院,一个学院有多个系

<?php
/**
 * Created by 憧憬.
 */
abstract class OrganizationComponent {
    private $name;
    private $des;
    /**
     * OrganizationComponent constructor.
     * @param $name
     * @param $des
     */
    public function __construct($name, $des)
    {
        $this->name = $name;
        $this->des = $des;
    }
    /**
     * @return mixed
     */
    public function getName()
    {
        return $this->name;
    }
    /**
     * @param mixed $name
     */
    public function setName($name): void
    {
        $this->name = $name;
    }
    /**
     * @return mixed
     */
    public function getDes()
    {
        return $this->des;
    }
    /**
     * @param mixed $des
     */
    public function setDes($des): void
    {
        $this->des = $des;
    }
    /**
     * 添加
     * @param OrganizationComponent $organizationComponent
     * @throws Exception
     * @author: 憧憬
     */
    public function add(OrganizationComponent $organizationComponent)
    {
        throw new Exception('没有add');
    }
    /**
     * 删除
     * @param OrganizationComponent $organizationComponent
     * @throws Exception
     * @author: 憧憬
     */
    public function remove(OrganizationComponent $organizationComponent)
    {
        throw new Exception('没有remove');
    }
    /**
     * 输出
     * @return mixed
     * @author: 憧憬
     */
    abstract public function iprint();
}
/**
 * 大学
 * 是Composite角色, 可以管理College
 * Class University
 */
class University extends OrganizationComponent {
    public $organizationComponents;
    /**
     * University constructor.
     * @param $name
     * @param $des
     */
    public function __construct($name, $des)
    {
        parent::__construct($name, $des);
        $this->organizationComponents = [];
    }
    public function add(OrganizationComponent $organizationComponent)
    {
        $this->organizationComponents[] = $organizationComponent;
    }
    public function remove(OrganizationComponent $organizationComponent)
    {
        foreach ($this->organizationComponents as $k => $component) {
            if ($component == $organizationComponent) {
                unset($this->organizationComponents[$k]);
            }
        }
    }
    public function getName()
    {
        return parent::getName(); // TODO: Change the autogenerated stub
    }
    public function getDes()
    {
        return parent::getDes(); // TODO: Change the autogenerated stub
    }
    /**
     * 输出University 包含的学院
     * @return mixed|void
     * @author: 憧憬
     */
    public function iprint()
    {
        echo '---------------'. $this->getName() .'--------学校' . PHP_EOL;
        foreach ($this->organizationComponents as $component) {
            $component->iprint();
        }
    }
}
/**
 * 学院
 * Class College
 */
class College extends OrganizationComponent {
    // 包含的college
    public $organizationComponents;
    /**
     * University constructor.
     * @param $name
     * @param $des
     */
    public function __construct($name, $des)
    {
        parent::__construct($name, $des);
        $this->organizationComponents = [];
    }
    public function add(OrganizationComponent $organizationComponent)
    {
        $this->organizationComponents[] = $organizationComponent;
    }
    public function remove(OrganizationComponent $organizationComponent)
    {
        foreach ($this->organizationComponents as $k => $component) {
            if ($component == $organizationComponent) {
                unset($this->organizationComponents[$k]);
            }
        }
    }
    public function getName()
    {
        return parent::getName(); // TODO: Change the autogenerated stub
    }
    public function getDes()
    {
        return parent::getDes(); // TODO: Change the autogenerated stub
    }
    /**
     * 输出University 包含的系
     * @return mixed|void
     * @author: 憧憬
     */
    public function iprint()
    {
        echo '---------------'. $this->getName() .'-------学院' . PHP_EOL;
        foreach ($this->organizationComponents as $component) {
            $component->iprint();
        }
    }
}
/**
 * 系 属于叶子结点 所以不需要重写add和remove
 * Class Department
 */
class Department extends OrganizationComponent {
    public function __construct($name, $des)
    {
        parent::__construct($name, $des);
        $this->organizationComponents = [];
    }
    public function iprint()
    {
        // TODO: Implement iprint() method.
        echo '-------------'.$this->getName(). '--------系'.PHP_EOL;
    }
}
// 创建学校
$university = new University('清华大学', '中国顶级大学');
// 创建学院
$computerCollege = new College('计算机学院', '计算机学院');
$infoEngineerCollege = new College('信息工程学院', '信息工程学院');
// 创建学院下的个个系
$computerCollege->add(new Department('软件工程', '软件工程ok'));
$computerCollege->add(new Department('网络工程', '网络工程ok'));
$computerCollege->add(new Department('计算机科学与技术', '计算机科学与技术ok'));
$infoEngineerCollege->add(new Department('通信工程', '通信工程不ok'));
$infoEngineerCollege->add(new Department('信息工程', '信息工程不ok'));
// 将学院加入学校
$university->add($computerCollege);
$university->add($infoEngineerCollege);
// 输出整个大学下面的子节点
$university->iprint();
echo PHP_EOL;
// 输出计算机学院下面的子节点
$computerCollege->iprint();
// 如果再要强化级别 只需要接着实现 组合进来就可以 比较方便


目录
相关文章
|
4月前
|
设计模式 JavaScript 前端开发
js设计模式【详解】—— 组合模式
js设计模式【详解】—— 组合模式
52 7
|
2月前
|
设计模式 Java
Java设计模式:组合模式的介绍及代码演示
组合模式是一种结构型设计模式,用于将多个对象组织成树形结构,并统一处理所有对象。例如,统计公司总人数时,可先统计各部门人数再求和。该模式包括一个通用接口、表示节点的类及其实现类。通过树形结构和节点的通用方法,组合模式使程序更易扩展和维护。
Java设计模式:组合模式的介绍及代码演示
|
2月前
|
设计模式 存储 安全
Java设计模式-组合模式(13)
Java设计模式-组合模式(13)
|
5月前
|
设计模式 存储 安全
Java设计模式:组合模式之透明与安全的两种实现(七)
Java设计模式:组合模式之透明与安全的两种实现(七)
|
5月前
|
设计模式 Java
Java设计模式之组合模式详解
Java设计模式之组合模式详解
|
5月前
|
设计模式
组合模式-大话设计模式
组合模式-大话设计模式
|
6月前
|
设计模式 Java 容器
【设计模式系列笔记】组合模式
组合模式(Composite Pattern)是一种结构型设计模式,它允许将对象组合成树状结构以表示部分-整体的层次结构。组合模式使得客户端可以统一处理单个对象和对象组合,而无需区分它们的类型。
85 12
|
6月前
|
设计模式 Go
[设计模式 Go实现] 结构型~组合模式
[设计模式 Go实现] 结构型~组合模式
|
6月前
|
设计模式 安全 Java
[设计模式Java实现附plantuml源码~结构型]树形结构的处理——组合模式
[设计模式Java实现附plantuml源码~结构型]树形结构的处理——组合模式
|
6月前
|
设计模式 Java
【设计模式】文件目录管理是组合模式吗?
【设计模式】文件目录管理是组合模式吗?
41 0

热门文章

最新文章

  • 1
    C++一分钟之-设计模式:工厂模式与抽象工厂
    42
  • 2
    《手把手教你》系列基础篇(九十四)-java+ selenium自动化测试-框架设计基础-POM设计模式实现-下篇(详解教程)
    46
  • 3
    C++一分钟之-C++中的设计模式:单例模式
    53
  • 4
    《手把手教你》系列基础篇(九十三)-java+ selenium自动化测试-框架设计基础-POM设计模式实现-上篇(详解教程)
    37
  • 5
    《手把手教你》系列基础篇(九十二)-java+ selenium自动化测试-框架设计基础-POM设计模式简介(详解教程)
    61
  • 6
    Java面试题:结合设计模式与并发工具包实现高效缓存;多线程与内存管理优化实践;并发框架与设计模式在复杂系统中的应用
    56
  • 7
    Java面试题:设计模式在并发编程中的创新应用,Java内存管理与多线程工具类的综合应用,Java并发工具包与并发框架的创新应用
    40
  • 8
    Java面试题:如何使用设计模式优化多线程环境下的资源管理?Java内存模型与并发工具类的协同工作,描述ForkJoinPool的工作机制,并解释其在并行计算中的优势。如何根据任务特性调整线程池参数
    49
  • 9
    Java面试题:请列举三种常用的设计模式,并分别给出在Java中的应用场景?请分析Java内存管理中的主要问题,并提出相应的优化策略?请简述Java多线程编程中的常见问题,并给出解决方案
    105
  • 10
    Java面试题:设计模式如单例模式、工厂模式、观察者模式等在多线程环境下线程安全问题,Java内存模型定义了线程如何与内存交互,包括原子性、可见性、有序性,并发框架提供了更高层次的并发任务处理能力
    75