设计模式——组合实体模式

ops/2024/11/25 11:01:41/

定义与概念

  • 组合实体模式(Composite Entity Pattern)是一种设计模式,主要用于将多个相关的实体组合成一个单一的实体,以实现对这些实体的统一管理和操作。这种模式在处理复杂的对象关系时非常有用,它将相关的数据和操作封装在一起,使得客户端可以更方便地与这些组合后的实体进行交互。
  • 例如,在一个人力资源管理系统中,员工的信息可能包括基本信息(如姓名、年龄)、工作信息(如职位、部门)和薪资信息(如基本工资、奖金)等多个部分。组合实体模式可以将这些不同部分的信息组合成一个 “员工组合实体”,客户端(如人事管理模块)在操作员工信息时,就可以通过这个组合实体来进行统一的操作,而不是分别处理每个部分的信息。

结构组成

  • 组合实体(Composite Entity):
    它是模式的核心部分,将多个相关的实体组合在一起。这个组合实体包含了对各个子实体的引用,并提供了统一的接口来操作这些子实体。例如,在上述人力资源管理系统的例子中,“员工组合实体” 类会包含员工基本信息对象、工作信息对象和薪资信息对象的引用,并且会有方法来获取和设置这些信息,如getEmployeeName()、setEmployeePosition()等。
  • 细粒度实体(Fine - Grained Entities):
    这些是被组合的实体,它们各自代表了组合实体的一个部分。每个细粒度实体都有自己的数据和操作方法。在人力资源系统中,员工基本信息类、工作信息类和薪资信息类就是细粒度实体。例如,员工基本信息类可能有属性name、age,以及方法getName()、setName()等。
  • 协调者(Coordinator):
    协调者主要负责创建和维护组合实体,它了解组合实体的构建过程和内部结构。协调者还负责处理客户端的请求,将请求转发给组合实体,并在必要时协调组合实体和细粒度实体之间的操作。在人力资源管理系统中,人事管理模块可以充当协调者的角色,它在创建新员工记录时,会构建 “员工组合实体”,并在需要修改或查询员工信息时,通过 “员工组合实体” 来完成操作。

工作原理

  • 协调者首先创建组合实体,在创建过程中,组合实体内部会创建或引用细粒度实体。客户端通过协调者来请求与组合实体相关的操作。协调者将请求转发给组合实体,组合实体根据请求的类型,调用自身内部的方法或者操作细粒度实体来完成请求。最后,组合实体将操作结果返回给协调者,协调者再将结果返回给客户端。
  • 例如,在一个游戏角色系统中,游戏角色是一个组合实体,它由角色属性(如力量、敏捷)、装备信息和技能信息等细粒度实体组成。游戏服务器(协调者)在玩家创建角色时,创建游戏角色组合实体,并初始化其内部的细粒度实体。当玩家请求查看角色属性时,服务器将请求转发给游戏角色组合实体,组合实体获取角色属性细粒度实体中的数据并返回给服务器,服务器再将数据展示给玩家。

代码示例

以下是一个简单的模拟学生信息管理的组合实体模式示例。

  • 细粒度实体 - 学生基本信息(StudentBasicInfo)
class StudentBasicInfo {
private:std::string name;int age;
public:void setName(const std::string& n) {name = n;}std::string getName() const {return name;}void setAge(int a) {age = a;}int getAge() const {return age;}
};
  • 细粒度实体 - 学生成绩信息(StudentScoreInfo)
class StudentScoreInfo {
private:float score;
public:void setScore(float s) {score = s;}float getScore() const {return score;}
};
  • 组合实体 - 学生信息(StudentInfo)
class StudentInfo {
private:StudentBasicInfo basicInfo;StudentScoreInfo scoreInfo;
public:void setName(const std::string& n) {basicInfo.setName(n);}std::string getName() const {return basicInfo.getName();}void setAge(int a) {basicInfo.setAge(a);}int getAge() const {return basicInfo.getAge();}void setScore(float s) {scoreInfo.setScore(s);}float getScore() const {return scoreInfo.getScore();}
};
  • 协调者 - 学生信息管理(StudentInfoManager)
class StudentInfoManager {
public:StudentInfo createStudent() {StudentInfo student;return student;}void updateStudentInfo(StudentInfo& student, const std::string& name, int age, float score) {student.setName(name);student.setAge(age);student.setScore(score);}void displayStudentInfo(const StudentInfo& student) {std::cout << "学生姓名: " << student.getName() << ", 年龄: " << student.getAge() << ", 成绩: " << student.getScore() << std::endl;}
};
  • 客户端使用示例
int main() {StudentInfoManager manager;StudentInfo student = manager.createStudent();manager.updateStudentInfo(student, "张三", 20, 85.0f);manager.displayStudentInfo(student);return 0;
}

优点

  • 统一管理:
    将多个相关的实体组合成一个整体,方便进行统一的管理和操作。在处理复杂的业务对象时,可以减少客户端与多个细粒度实体之间的交互复杂性,提高了代码的可读性和可维护性。例如,在企业资源规划(ERP)系统中,对于复杂的产品信息(包括产品基本信息、库存信息、销售信息等),使用组合实体模式可以让客户端通过一个接口来操作所有相关信息。
  • 封装性好:
    组合实体对内部的细粒度实体进行了封装,客户端不需要了解内部实体的具体细节和它们之间的复杂关系。这使得系统的内部结构更加清晰,并且在内部实体发生变化时,只要组合实体的接口保持不变,客户端代码就不需要修改。例如,在一个图形绘制系统中,如果对图形的颜色信息实体进行内部结构调整,只要图形组合实体的颜色获取和设置接口不变,使用图形组合实体的绘图模块就不会受到影响。
  • 符合面向对象设计原则:
    这种模式体现了面向对象设计中的聚合和封装原则,使得系统的设计更加符合面向对象的思想,有利于构建复杂的软件系统。例如,在一个物流管理系统中,订单信息可以作为组合实体,将发货信息、收货信息、商品信息等细粒度实体聚合在一起,这样的设计符合对象之间的实际关系,便于理解和维护。

缺点

  • 增加复杂度:
    引入组合实体和协调者增加了系统的层次结构和复杂度。对于简单的系统来说,可能会显得过于复杂,并且在设计和实现过程中需要考虑更多的因素,如组合实体和细粒度实体之间的交互方式、协调者的职责等。例如,在一个小型的命令行工具中,如果使用组合实体模式来管理简单的数据,可能会使代码变得臃肿和难以理解。
  • 可能导致性能问题:
    由于组合实体需要管理多个细粒度实体,在某些情况下,频繁地操作组合实体可能会导致性能下降。例如,在一个对性能要求极高的实时数据处理系统中,如果组合实体的内部操作涉及大量的数据复制或者复杂的对象关系处理,可能会影响系统的整体性能。

http://www.ppmy.cn/ops/136547.html

相关文章

解决k8s拉取私有镜像401 Unauthorized 问题

拉取镜像时未指定账户和密码通常是因为需要访问的镜像仓库启用了认证&#xff0c;但 Kubernetes 默认配置中未提供访问凭据。要解决此问题&#xff0c;可以按照以下步骤配置镜像仓库的认证信息&#xff1a; 1. 创建 Kubernetes Secret 为镜像仓库配置访问凭据&#xff0c;使用…

量子感知机

神经网络类似于人类大脑&#xff0c;是模拟生物神经网络进行信息处理的一种数学模型。它能解决分类、回归等问题&#xff0c;是机器学习的重要组成部分。量子神经网络是将量子理论与神经网络相结合而产生的一种新型计算模式。1995年美国路易斯安那州立大学KAK教授首次提出了量子…

2024年北京海淀区中小学信息学竞赛(初赛)试题

来源&#xff1a;2024年北京海淀区中小学信息学竞赛&#xff08;初赛&#xff09;试题 | 6547网 2024年北京海淀区中小学信息学竞赛&#xff08;初赛&#xff09;试题 题目总数&#xff1a;24 总分数&#xff1a;100 单项选择题(共有 15 道小题&#xff0c;每道小题3分&am…

【Qt】控件LineEdit

1.QcalendarWidget 获取点击的时间&#xff0c;显示在lineedit上 2.QLineEdit 1.QLineEdit设置内部提示 ui->name->setPlaceholderText("请输入名字");//设置内部提示2.设置快捷删除 ui->name->setClearButtonEnabled(true);//设置一键清除3.设置…

彻底理解Redis的过期策略

一.由来 因为现在Redis的使用是非常普遍的&#xff0c;Redis是基于内存的数据存储系统&#xff0c;而内存相比于早些年而言&#xff0c;还是便宜了很多&#xff0c;但是相比硬盘而言还是最很多&#xff0c;因此提高Redis里面的内存利用率是非常重要&#xff0c;而Redis的过期策…

Vue3 生命周期钩子详解

Vue3 生命周期钩子详解 简介 Vue3的生命周期钩子让我们能够在组件的不同阶段执行自定义代码。与Vue2相比&#xff0c;Vue3的生命周期钩子在Composition API中有了新的使用方式&#xff0c;但整体概念保持一致。 基础知识 Vue3中的生命周期钩子可以通过两种方式使用&#xf…

C程序设计语言 第二章 类型、运算符与表达式

变量和常量是程序处理的两种基本数据对象。声明语句说明变量的名字及类型&#xff0c;也可以指定变量的初值。运算符指定将要进行的操作。表达式则把变量与常量组合起来生成新的值。对象的类型决定该对象可取值的集合以及可以对该对象执行的操作。本章将详细讲述这些内容。 AN…

C指针之舞——指针探秘之旅(2)

❤博客主页&#xff1a;折枝寄北-CSDN博客 ❤专栏&#xff1a;C语言学习专栏 在上一篇博客文章&#xff1a;C指针之舞——指针探秘之旅-CSDN博客中&#xff0c;我们学习了字符指针&#xff0c;指针数组&#xff0c;数组指针&#xff0c;数组传参和指针传参等内容&#xff0c;…