组合模式与职责链模式编程实现

2023-05-16

组合模式

简介

将对象组合成树形结构以表示“部分-整体”的层次结构。
组合模式使得用户对单个对象和组合对象的使用具有一致性。
动机

总部、分部和办事处是成树状结构,也就是有组织结构的,不可以简单的平行管理。
希望总公司的组织结构,比如人力资源部、财务部的管理功能可以复用于分公司。这其实是整体与部分可以被一致对待的问题。
适用性

想表示对象的“部分-整体”层次结构。
希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。
结构

在这里插入图片描述
参与者

Component
为组合中的对象声明接口。
在适当的情况下,实现所有类共有接口的缺省行为。
声明一个接口用于访问和管理Component的子组件。
在递归结构中定义一个接口,用于访问一个父部件,并在合适的情况下实现它。(可选)
Leaf
在组合中表示叶节点对象,叶节点没有子节点。
在组合中定义叶节点对象的行为。
Composite
定义有子部件的那些部件的行为。
存储子部件。
在Component接口中实现与子部件有关的操作。
Client
通过Component接口操纵组合部件的对象。

协作

用户使用Component类接口与组合结构中的对象进行交互。
如果接收者是一个叶节点,则直接处理请求。
如果接收者是一个Composite,它通常将请求发送给它的子部件,在转发请求之前与/或之后可能执行一些辅助操作。
效果

定义了包含基本对象和组合对象的类层次结构。
简化客户代码。
使得更容易添加新类型的组件。

职责链模式

简介

为解除请求的发送者和接收者之间的耦合,而使多个对象都有机会处理这个请求。
将这些对象连成一条链,并沿着这条链传递该请求,指导有一个对象处理它为止。
动机

考虑公司中的请假申请。
公司中管理人员按等级从低到高分别有:经理、总监、总经理。
请假需要根据天数长短,向不同等级的管理人员申请,例如少于2天直接向经理申请即可,少于一周必须要总监批准,更长时间则需要总经理批准。
适用性

有多个对象可以处理一个请求,哪个对象处理该请求运行时刻自动确定。
想在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。
可处理一个请求的对象集合应被动态指定。
结构

在这里插入图片描述

参与者

Handler
定义一个处理请求的接口。
实现后继链。
ConcreteHandler
处理它所负责的请求。
可访问它的后继者。
如果可处理该请求,就处理之;否则将该请求转发给它的后继者。
Client
向链上的ConcreteHandler对象提交请求。
效果

降低耦合度。
增强了给对象指派职责的灵活性。
不保证被接受。

实例

根据下图,利用组合模式构建该公司的结构。
在这里插入图片描述

即总公司下设上海华东分公司,华东分公司下设南京办事处和杭州办事处。其中,各级分公司均设有人力资源部和财务部。

利用组合模式构建好该结构后,利用职责链模式处理各地员工加薪请求。

例如,一南京员工提出加薪请求,如果加薪不超过1000元,南京办事处即可批准;如果超过1000元,则上报华东分公司,如果2000元以内,则批准;超过则上报北京总公司,如果不超过3000元,则总公司批准,否则拒绝。

UML
在这里插入图片描述

组合模式Component是对象声明接口,对应于职责链模式的Handler,两个模式的代码可以合并。

另外通过增加low, bound两个变量来控制if语句数量,减少类的数目。因此职责链中的多个ConcreteHandler对应于一个具体的ConcreteCompany。

代码

#include<iostream>
#include<list>
#include <typeinfo>
 
using namespace std;
 
class Component{
public:
    Component(string name){
        this->name = name;
    }
    virtual void Add(Component* c) = 0;
    virtual void Remove(Component* c) = 0;
    virtual void Display(int depth) = 0;
    void SetSuccessor(Component* s){
        this->successor = s;
    }
    void SetBound(int low, int high){
        this->low = low;
        this->high = high;
    }
    virtual void HandleReauest(int request) = 0;
protected:
    string name;
    int low, high;
    Component* successor;
};
 
class Subcom : public Component{
public:
    Subcom(string name) : Component(name){}
    void Add(Component* c){
        cout<<"Cannot add to a leaf";
    }
    void Remove(Component* c){
        cout<<"Cannot remove from a leaf";
    }
    void Display(int depth){
        for(int i = 0; i <= depth; i++)
            cout<<"--";
        cout<<name<<endl;
    }
    void HandleReauest(int request){
        
    }
};
 
class ConcreteCompany: public Component{
private:
    list<Component*> children;
public:
    ConcreteCompany(string name): Component(name){}
    void Add(Component *c){
        children.push_back(c);
    }
    void Remove(Component *c){
        children.remove(c);
    }
    void Display(int depth){
        for(int i = 0; i <= depth; i++)
            cout<<"--";
        cout<<name<<endl;
        for(Component* child : children){
            child->Display(depth + 1);
        }
    }
    void HandleReauest(int request){
        if(request >= low && request <= high){
            cout<<this->name<<"处理请求: "<<request<<endl;
        }else if(successor != NULL){
            cout<<this->name<<"处理失败"<<endl;
            successor->HandleReauest(request);
        }else{
            cout<<this->name<<"加薪拒绝"<<request<<endl;
        }
    }
};
 
/* 
即总公司下设上海华东分公司,华东分公司下设南京办事处和杭州办事处。其中,各级分公司均设有人力资源部和财务部。
 
用组合模式构建好该结构后,利用职责链模式处理各地员工加薪请求。
 
例如,一南京员工提出加薪请求,如果加薪不超过1000元,南京办事处即可批准;如果超过1000元,则上报华东分公司,如果2000元以内,则批准;超过则上报北京总公司,如果不超过3000元,则总公司批准,否则拒绝。、
 
实验报告内容:	
 
 */
 
 
int main(){
    Component *root = new ConcreteCompany("总公司");
    root->Add(new Subcom("人力资源部"));
    root->Add(new Subcom("财务部"));
    root->SetBound(2000, 3000);
 
    Component *huadong = new ConcreteCompany("上海华东分公司");
    huadong->Add(new Subcom("人力资源部"));
    huadong->Add(new Subcom("财务部"));
    huadong->SetBound(1000, 2000);
 
 
    Component *nanjing = new ConcreteCompany("南京办事处");
    nanjing->Add(new Subcom("人力资源部"));
    nanjing->Add(new Subcom("财务部"));
    nanjing->SetBound(0, 1000);
 
    Component *hanzhou = new ConcreteCompany("杭州办事处");
    hanzhou->Add(new Subcom("人力资源部"));
    hanzhou->Add(new Subcom("财务部"));
    hanzhou->SetBound(0, 1000);
 
    nanjing->SetSuccessor(huadong);
    hanzhou->SetSuccessor(huadong);
    huadong->SetSuccessor(root);
    root->SetSuccessor(NULL);
    huadong->Add(nanjing);
    huadong->Add(hanzhou);
 
    root->Add(huadong);
    root->Display(1);
    cout<<"*********************"<<endl;
    nanjing->HandleReauest(100);
    cout<<"*********************"<<endl;
    hanzhou->HandleReauest(1500);
    cout<<"*********************"<<endl;
    hanzhou->HandleReauest(2100);
    cout<<"*********************"<<endl;
    hanzhou->HandleReauest(3100);
    return 0;
}
//

结果

在这里插入图片描述

总结

①本次需要将职责链模式与组合模式合并,其中组合模式Component是对象声明接口,对应于职责链模式的Handler。

②组合模式中的节点需要放到当前父节点的list中,对于容器list,需要掌握对应的STL语句。

③对于职责链模式,为了减少类的数量和耦合需要设置low和high两个上下界。类虽然少了,但是对象没有减少,这些对象形成一条链,并沿着这条链传递该请求,直到有一个对象处理了它为止。通过当前对象的name来指示客户端选择。

更多内容访问 omegaxyz.com
网站所有代码采用Apache 2.0授权
网站文章采用知识共享许可协议BY-NC-SA4.0授权
© 2019 • OmegaXYZ-版权所有 转载请注明出处

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

组合模式与职责链模式编程实现 的相关文章

  • hive2.0.1执行存储过程

    1 编写过程sql 基于上篇文章的test db库 xff0c vi test sql xff0c 新增 xff1a use test db begin insert into t test2 id name values 2 39 你好
  • Centos7下搭建MySQL高可用架构(互为主从)

    1 环境介绍 192 168 31 14 A机器 192 168 31 82 B机器 192 168 31 200 vip xff08 A主B从 xff09 2 安装mysql 2 1 创建配置文件 xff1a vi mysql cnf m
  • JAVA基础篇-文件分片与合成实践

    本文提供两种文件分片与合成的方法 xff0c 分别是普通IO流的方式和使用RandomAccessFile的方式 xff0c 推荐RandomAccessFile方式 xff0c 接下来请看代码实现 xff1a package com st
  • GitBook快速入门

    1 安装 Node js Node 官网已经把 linux 下载版本更改为已编译好的版本了 xff0c 我们可以直接下载解压后使用 xff1a wget https nodejs org dist v10 15 3 node v10 15
  • 基于jsonp和cookie实现单点登录

    1 SSO需求 当前域名A xff1a www abc com 跨域域名B xff1a www def com 当在A域名下登录后点击链接跳转至域名B xff0c 希望实现域名B免登录 2 实现思路 2 1域名A开发一个接口C xff1a
  • 基于docker安装破解jira7.11.1

    1 拉取jira的docker镜像 docker pull cptactionhank atlassian jira software 7 11 1 2 启动jira容器 docker run name jira detach restar
  • Shell命令学习

    Shell命令 文章目录 Shell命令一 Shell是什么 xff1f 二 linux环境下的快捷键tab xff1a 输入命令或者路径等操作时自动补全上键 xff1a 快速选择上一次或多次执行的命令下键 xff1a 快速选择下一次或多次
  • 关于onNewIntent理解

    首先介绍一下Android的四种启动模式 standard 默认的 xff1a 所有的activity实例放在一个task xff08 任务栈 xff09 中 xff0c 遵循先进后出 xff0c 后进先出的规则 singleTop xff
  • ubuntu20.04系统安装谷歌浏览器

    1 百度搜索 谷歌浏览器官网 xff0c 然后在搜索界面点击如图所示图标进入谷歌浏览器下载界面 2 在谷歌浏览器下载界面 xff0c 点击 下载Chrome 3 在弹出的下载界面选择Ubuntu适用的64位下载包后点击 接受并安装 4 在下
  • 【Algorithm】单向链表模拟实现vector功能

    span class token function cmake minimum required span span class token punctuation span VERSION span class token number
  • ARCH INSTALL

    Arch Linux Install With UEFI Boot gdisk dev sdxy boot always uses less than 1G uses EF00 EFI System home uses 8302 mnt u
  • SQL Server 表注释&列注释

    添加表注释 表加注释 EXEC sys sp addextendedproperty 64 name 61 N 39 MS Description 39 64 value 61 N 39 注释内容 39 64 level0type 61 N
  • 在ubuntu14.04上安装或升级git

    git version git version 1 9 1 可以使用下面命令升级git xff08 如果不是root用户 xff0c 需在命令前加sudo xff09 xff1a add apt repository ppa git cor
  • C#串口数据处理--环形缓冲区-FIFO

    一 FIFO环形缓冲区初始化 static int MAX BUFFER LEN 61 1024 定义缓冲区大小 FIFO receiveBufferManager 61 new FIFO MAX BUFFER LEN 二 串口接收事件中添
  • IDEA 解决jar冲突问题

    在实际的 Maven 项目开发中 xff0c 由于项目引入的依赖过多 xff0c 遇到 jar 冲突算是一个很常见的问题了 如何使用 IntelliJ IDEA 解决 jar 包冲突的问题 xff01 简单粗暴 xff0c 直接上示例 xf
  • Ubuntu 18.04下安装Google Chrome

    Ubuntu 18 04下安装Google Chrome 进入Chrome官网下载地址 xff1a https www google cn intl zh CN chrome 点击 下载Chrome xff0c 进入下载页面 xff1a 如
  • css获取网页内所有标签的内容

    选择所有标签内的内容 包括script和style xff1a span class token punctuation span span class token punctuation span text 选择除script和style
  • Ubuntu 22.04 dektop 开启root并自动登录桌面

    1 设置root密码 span class token function sudo span span class token function passwd span root 2 解锁root span class token func
  • linux服务器之间的数据拷贝

    方法一 xff1a scp xff08 secure copy xff09 安全拷贝 xff08 1 xff09 scp定义 xff1a scp可以实现服务器与服务器之间的数据拷贝 xff08 from server1 to server2
  • Ubuntu桌面美化方法记录

    Ubuntu 20 04 1 LTS 桌面系统主题 xff0c 图标美化记录 Ubuntu使用的是Gnome Desktop xff0c 可以在 Gnome Look 寻找需要的主题 xff0c 图标 xff0c 插件等来丰富桌面系统 本文

随机推荐