9、组合模式(结构性模式)

news2025/1/15 17:19:17

        组合模式又叫部分整体模式,它创建了对象组的树形结构,将对象组合成树状结构,以一致的方式处理叶子对象以及组合对象,不以层次高低定义类,都是结点类

       一、传统组合模式

        举例,大学、学院、系,它们之间不是继承关系,是组合关系:大学由学院组成,学院由系组成,但是它们都是组织结点,一个大学,n个学院,一个学院m个系,大学、学院是 组合类型的,它们都包含结点成员,系是 叶子类型 的,不包含结点成员

        把大学类、学院类、系类抽象为组织结点类,它们都是组织结点类的子类(其中大学子类、学院子类是组合类型的类,系是叶子类型的类),按照具体依赖抽象原则,以子类共有的属性和行为来定义结点类,代码如下:

//组织结点(基类)Organization
class Organization{                      //具体依赖抽象原则
	std::string name;//数据成员
public:
	Organization( std::string name):name(name) { }//构造函数
	virtual ~Organization(){ }                    //虚析构
	//其他成员函数
    virtual std::string getName(){ return name; }   
    virtual void add(Organization* o){ throw "叶子结点没有成员!\n"; }
    //virtual void remove( ){ throw "叶子结点没有成员!\n";  }
    virtual void print() = 0;  //
};    

        组合类型的子类University、College,重写基类成员函数,代码几乎一样

//组合类型(子类)University College
//University
class University:public Organization{
	std::list<Organization*> ul; //以基类的形式包含其他子类对象
public:
	University(std::string name):Organization(name) { }
	~University(){
		std:: cout << "~University\n";
		for(auto o:ul){ delete o; }		
	}
	//重写
	virtual void add(Organization* o){
		ul.push_back(o);
	}
    virtual void print(){
		std::cout << getName() << "\n";//基类成员获取,基类的成员也是子类的组成部分
		for( auto o:ul ){
			o->print();
		}
	}	
};

//College
class College:public Organization{
	std::list<Organization*> cl; //以基类的形式包含其他子类对象
public:
	College(std::string name):Organization(name) { }
	~College(){
		std:: cout << "~College\n";
		for(auto o:cl){ delete o; }		
	}
	//重写
	virtual void add(Organization* o){
		cl.push_back(o);
	}
    virtual void print(){
		std::cout << getName() << "\n";//基类成员获取,基类的成员也是子类的组成部分
		for( auto o:cl ){
			o->print();
		}
	}	
};

        叶子类型的子类(Department)

//叶子类型(子类)Department
class Department:public Organization{
public:
	Department(std::string name):Organization(name) { }
	~Department(){
		std:: cout << "~Department\n";
	}
	//重写
	virtual void print(){
		std::cout << getName() << "\n";
	}
};

        头文件及测试代码

#include <iostream>
#include <string>
#include <exception>
#include <list>

int main() 
{
	University u("清华大学");
	Organization* c1 = new College("计算机学院");
	Organization* c2 = new College("信息工程学院");
	Organization* d = new Department("信息工程");
	u.add( c1 );
	u.add( c2 );
	c2->add( d );
	u.print();
	//c2->print();	
    return 0;
}

        二、组合模式的结点设计

        把组合类型的的属性、行为都放到结点,以对象组是否为空来判断是叶子类型的还是组合类型的,这样叶子类型也可以扩展为组合类型,虽然看起来有点混乱,但是确实可行,比如系原来是叶子,现在有了个学生会,添加成员后就可以不是叶子了

#include <iostream>
#include <string>
#include <exception>
#include <list>
 
//组织结点(基类)Organization
class Organization{  //具体依赖抽象原则
	std::string name;//数据成员
	std::list<Organization*> ol; //对象组
public:
	Organization( std::string name):name(name) { } //构造函数
	virtual ~Organization(){	 //虚析构
		for(auto o:ol){ delete o; }	
	}                    
	//其他成员函数 
    virtual void add(Organization* o){ ol.push_back(o); }	
    virtual void print(){
		std::cout << name << "\n";
		if( !ol.empty() ) //判断是否是叶子结点
		{ 
			for( auto o:ol ){
				o->print();
			}
		}	
	}
};    
 
//University
class University:public Organization{
public:
	University(std::string name):Organization(name) { }
	~University(){ std:: cout << "~University\n"; }
};
 
//College
class College:public Organization{
	std::list<Organization*> cl; //以基类的形式包含其他子类对象
public:
	College(std::string name):Organization(name) { }
	~College(){
		std:: cout << "~College\n";
	}
};
 
//Department
class Department:public Organization{
public:
	Department(std::string name):Organization(name) { }
	~Department(){
		std:: cout << "~Department\n";
	}
};
 
//StudentUnion
class StudentUnion:public Organization{
public:
	StudentUnion(std::string name):Organization(name) { }
	~StudentUnion(){
		std:: cout << "~StudentUnion\n";
	}
};
 
int main() 
{
	University u("清华大学");
	Organization* c1 = new College("计算机学院");
	Organization* c2 = new College("信息工程学院");
	Organization* d1 = new Department("信息工程");
	Organization* d2 = new Department("软件工程");
	Organization* s = new StudentUnion("信息工程学生会");
	
	d1->add( s );
	c1->add( d2 );
	c2->add( d1 );
	
	u.add( c1 );
	u.add( c2 );
	
	u.print( );
	//c2->print( );	
    return 0;
}

        三、修改打印函数,打印出树形结构

         1、 修改print

    virtual void print( int depth ){
		for(int i=0; i< depth; ++i)
			std:: cout << "--";
		std::cout << name << "\n";
		if( !ol.empty() ) //判断是否是叶子结点
		{ 
			for( auto o:ol ){
				o->print(depth+1);
			}
		}	
	}

        2、调用修改为

u.print(0);
//c2->print( 0 );

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1513803.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

勾八头歌之数据科学导论—数据预处理

第1关&#xff1a;引言-根深之树不怯风折&#xff0c;泉深之水不会涸竭 第2关&#xff1a;数据清理-查漏补缺 import numpy as np import pandas as pd import matplotlib.pyplot as pltdef student():# Load the CSV file and replace #NAME? with NaNtrain pd.read_csv(Tas…

人工智能的幽默“失误”

人工智能迷惑行为大赏 随着ChatGPT热度的攀升&#xff0c;越来越多的公司也相继推出了自己的AI大模型&#xff0c;如文心一言、通义千问等。各大应用也开始内置AI玩法&#xff0c;如抖音的AI特效&#xff5e;在使用过程中往往会遇到一些问题&#xff0c;让你不得不怀疑&#x…

反向传播 — 简单解释

一、说明 关于反向传播&#xff0c;我有一个精雕细刻的案例计划&#xff0c;但是实现了一半&#xff0c;目前没有顾得上继续充实&#xff0c;就拿论文的叙述这里先起个头&#xff0c;我后面将修改和促进此文的表述质量。 二、生物神经元 大脑是一个由大约100亿个神经元组成的复…

HD_VG_130M数据集预处理

数据集介绍 HD_VG_130M是文生视频常用数据集&#xff0c;其视频来源于油管&#xff0c;可通过该谷歌云盘链接下载官方文件&#xff0c;如下所示&#xff0c;其中metafiles中包含20个json文件&#xff0c;请先将其全部下载到本地&#xff0c;假设保存地址为"E:/HD_VG_130M…

Android Gradle 开发与应用 (六) : 创建buildSrc插件和使用命令行创建Gradle插件

1. 前言 前文中&#xff0c;我们介绍了在Android中&#xff0c;如何基于Gradle 8.2&#xff0c;创建Gradle插件。这篇文章&#xff0c;我们以buildSrc的方式来创建Gradle插件。此外&#xff0c;还介绍一种用Cmd命令行的方式&#xff0c;来创建独立的Gradle插件的方式。 1.1 本…

开源大数据集群部署(十五)Zookeeper集群部署

作者&#xff1a;櫰木 1、集群规划 主机版本角色系统用户hd1.dtstack.com3.7.1followerzookeeperhd2.dtstack.com3.7.1leaderzookeeperhd3.dtstack.com3.7.1followerzookeeper 2、zookeeper kerberos主体创建 在生产中zk服务端和客户端票据可以设置成不通名称或相同名称&am…

钉钉与实在智能达成战略合作,实在Agent助力钉钉AI助理成为“新质生产力”

3月12日&#xff0c;浙江实在智能科技有限公司&#xff08;简称“实在智能”&#xff09;与钉钉&#xff08;中国&#xff09;信息技术有限公司&#xff08;简称“钉钉”&#xff09;签署战略合作协议&#xff0c;达成战略合作伙伴关系。 未来&#xff0c;基于双方创新领先的技…

普乐蛙VR航天体验馆设备VR体验带你登陆月球

周末节假日这款设备人流量chao多&#xff01;景区&#xff1f;游乐场&#xff1f;电玩城爆滿&#xff0c;小编去了一次可是天天惦记着&#xff0c;学习/竞速/休闲/末日/kongbu&#xff0c;各种题材好过瘾&#xff01; 亲测不踩雷设备推荐&#xff01;华夏方舟——VR小白必玩的大…

学习Java的第九天

本章将学习什么是类的无参、带参方法又是什么 一、什么是类的无参方法 类是由一组具有相同属性和共同行为的实体抽象而来。对象执行的操作是通过编写类的方法实现的。显而易见&#xff0c;类的方法是一个功能模块&#xff0c;其作用是“做一件事情”。 1、类的方法必须包括以…

吴恩达机器学习笔记 十七 通过偏差与方差诊断性能 正则化 偏差 方差

高偏差&#xff08;欠拟合&#xff09;&#xff1a;在训练集上表现得也不好 高方差&#xff08;过拟合&#xff09;&#xff1a;J_cv要远大于J_train 刚刚好&#xff1a;J_cv和J_train都小 J_cv和J_train与拟合多项式阶数的关系 从一阶到四阶&#xff0c;训练集的误差越来越小…

走进AI新时代:织信低代码的实践与启示

最近 AIGC 很火&#xff0c;在各个领域都玩出了一些新花样。 比如在“低代码”领域&#xff0c;可以通过 AI 自动生成一个网站门户。 但这会带来开发效率的提升吗&#xff1f;如果 AI 能快速开发网站、APP等业务应用&#xff0c;那么 AI 生成能否完全取代低代码的可视化配置&a…

Java学习笔记------常用API

Math类 常用方法&#xff1a; 1. publicb static int abs(int a) 获取参数绝对值 2. publicb static double ceil(double a) 向上取整 3. publicb static floor(double a) 向下取整 4.public static int round(float a) 四舍五入 5. publicb static int max…

慎投!又新增1区SCI期刊被“On Hold”,共15本期刊正在调查中!

【SciencePub学术】近日&#xff0c;经小编查询&#xff0c;又新增一本SCI期刊被“暂停调查”&#xff01;该期刊隶属于TAYLOR & FRANCIS旗下&#xff0c;是一本JCR1区中科院4区的预警期刊。期刊详情如下&#xff1a; 01 新增“On Hold”期刊详情 BIOENGINEERED ISSN&…

【系统架构设计师】系统工程与信息系统基础 01

系统架构设计师 - 系列文章目录 01 系统工程与信息系统基础 文章目录 系列文章目录 前言 一、系统工程 ★ 二、信息系统生命周期 ★ 信息系统建设原则 三、信息系统开发方法 ★★ 四、信息系统的分类 ★★★ 1.业务处理系统【TPS】 2.管理信息系统【MIS】 3.决策支持系统…

java算法第22天 | ● 235. 二叉搜索树的最近公共祖先 ● 701.二叉搜索树中的插入操作 ● 450.删除二叉搜索树中的节点

235. 二叉搜索树的最近公共祖先 思路&#xff1a; 之前做过普通二叉树求共工作祖先的问题&#xff0c;有两种情况&#xff0c; 第一种是&#xff1a;如果一个节点的左孩子和右孩子分别包含p&#xff0c;q节点&#xff0c;那么这个节点是p和q的最近公共祖先。第二种是&#xff…

C++17中引入STL算法执行策略

C算法是一组预定义函数&#xff0c;可以对容器(例如数组、向量和列表)执行各种操作。这些算法具有定义的执行策略(have a defined execution policy)&#xff0c;决定它们如何执行以及如何与底层硬件交互。STL算法执行策略首先在C17标准中引入。 C17标准引入了三种新的执…

07 数据结构之图

# Makefile CCgcc CFLAGS -g -Wall SRCStest.c graph.c link_queue.c OBJS$(SRCS:.c.o) #variable replace APPtestall:$(OBJS) #指定一个目标&#xff0c; 不然默认目标不会检查依赖文件的时间戳$(CC) $(SRCS) -o $(APP) .PH…

Docker安装Prometheus监控

环境初始化 关闭防火墙 setenforce 0 vim /etc/selinux/config ##################内部代码################### SELINUXdisabled #关闭防火墙 ############################################ 安装docker #卸载yum源之前的docker安装包 sudo yum remove docker docker-clie…

如果你准备进入安全行业,入门应该做的

教育阶段 网络安全是一门高级学科。网络安全人员通常来自三个领域&#xff1a;系统管理、网络、开发。 假设你没有任何这些方面的背景&#xff0c;并且你需要从零开始。如果你在学生阶段的年龄&#xff1f; 这时有三种方法可选&#xff1a;大学、职业学校、资质证书 建议读计…

意大利数据监管机构对Sora展开调查

意大利数据保护监管机构 Garante3月8日宣布&#xff0c;将对 OpenAI 新推出的视频人工智能模型 Sora 展开隐私调查。 监管机构虽然没有对 OpenAI 提出任何具体指控&#xff0c;但表示正在研究 Sora 对意大利&#xff08;包括欧盟&#xff09;个人数据使用可能产生的潜在影响&am…