新版MQL语言程序设计:组合模式的原理、应用及代码实现

本文主要是介绍新版MQL语言程序设计:组合模式的原理、应用及代码实现,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

    • 一、什么组合模式
    • 二、为什么需要组合模式
    • 三、组合模式的实现原理
    • 四、组合模式的应用场景
    • 五、组合模式的代码实现

一、什么组合模式

组合模式是一种结构型设计模式,它允许将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。

二、为什么需要组合模式

  • 简化客户端代码:组合模式通过将对象组织成树形结构,使得客户端可以一致地对待单个对象和组合对象。客户端无需关心处理的是单个对象还是组合对象,从而简化了客户端的代码。

  • 提供一致的操作接口:组合模式定义了一致的操作接口,使得客户端可以透明地操作单个对象和组合对象。客户端无需关心具体是哪个对象,只需要调用相同的方法即可。

  • 支持递归组合:组合模式支持递归组合,即一个组合对象可以包含其他组合对象作为子节点。这样可以方便地处理复杂的层次结构,使得系统更加灵活和可扩展。

  • 简化添加新对象:由于组合模式使用了统一的接口,添加新的对象变得非常简单。无论是添加单个对象还是组合对象,都只需要实现相同的接口即可。

  • 提高代码复用性:组合模式可以通过递归组合的方式复用已有的对象。通过将对象组织成树形结构,可以灵活地复用已有的对象,从而提高代码的复用性。

三、组合模式的实现原理

  1. 定义一个抽象基类(Component):该类是组合中所有对象的共同接口,声明了一些操作方法,例如添加、删除、获取子节点等。
  2. 定义叶子类(Leaf):表示组合中的叶子节点,它没有子节点,实现了抽象基类中的操作方法。
  3. 定义容器类(Composite):表示组合中的容器节点,它可以包含子节点,实现了抽象基类中的操作方法。容器类中通常会有一个子节点列表用于存储子节点。
  4. 在容器类中实现对子节点的操作方法:例如添加、删除、获取子节点等。这些操作方法可以递归地调用子节点的相应方法,从而实现对整个树形结构的操作。
  5. 客户端使用组合模式:客户端可以通过抽象基类来统一对待单个对象和组合对象,从而简化了客户端的代码。客户端可以通过调用操作方法来对整个树形结构进行操作。

四、组合模式的应用场景

  1. 当需要表示对象的部分-整体层次结构,并且希望客户端能够以统一的方式处理单个对象和对象组合时,可以使用组合模式。
  2. 当希望忽略对象组合和单个对象之间的差异,统一对待它们时,可以使用组合模式。
  3. 当希望在不同层次上对对象进行操作,而不需要关心对象是单个对象还是对象组合时,可以使用组合模式。

五、组合模式的代码实现

//+------------------------------------------------------------------+
//| structure                                                        |
//+------------------------------------------------------------------+
//
//     |Client|----->|    Component    |*<------------------+
//                   |-----------------|                    |
//                   |Operation()      |                    | 
//                   |Add(Component)   |                    |
//                   |Remove(Component)|                    |
//                   |GetChild(int)    |                    |
//                            ^                             |
//                            |                             |
//                    +-------+-----------+                 |
//                    |                   |           nodes |
//              |   Leaf    |   |     Composite     |o------+
//              |-----------|   |-------------------|
//              |Operation()|   |Operation()        |
//                              | for all n in nodes|
//                              |  n.Operation()    |
//                              |Add(Component)     |
//                              |Remove(Component)  |
//                              |GetChild(int)      |
//
//+------------------------------------------------------------------+
//| typical object structure                                         |
//+------------------------------------------------------------------+
//
//                        +---->|aLeaf|
//                        |
//       |aComposite|-----+---->|aLeaf|         +---->|aLeaf|
//                        |                     |
//                        +---->|aComposite|----+---->|aLeaf|
//                        |                     |
//                        +---->|aLeaf|         +---->|aLeaf|
//
// 组件
class Component
{public:virtual void      Operation(void)=0;virtual void      Add(Component*)=0;virtual void      Remove(Component*)=0;virtual Component*   GetChild(int)=0;Component(void);Component(string);protected:string            name;
};
Component::Component(void) {}
Component::Component(string a_name):name(a_name) {}#define ERR_INVALID_OPERATION_EXCEPTION   1
// 向叶添加/删除组件时出现用户错误
// 表示>叶对象<合成
// 没有孩子
// 定义>行为>组合中的基本体对象
class Leaf:public Component
{public:void              Operation(void);void              Add(Component*);void              Remove(Component*);Component*        GetChild(int);Leaf(string);
};
void Leaf::Leaf(string a_name):Component(a_name) {}
void Leaf::Operation(void) {Print(name);}
void Leaf::Add(Component*) {SetUserError(ERR_INVALID_OPERATION_EXCEPTION);}
void Leaf::Remove(Component*) {SetUserError(ERR_INVALID_OPERATION_EXCEPTION);}
Component* Leaf::GetChild(int) {SetUserError(ERR_INVALID_OPERATION_EXCEPTION); return NULL;}// 定义>具有子级的组件的行为
// 存储>子组件
// 在组件接口中实现>子相关操作>
// 组合
class Composite:public Component
{public:void              Operation(void);void              Add(Component*);void              Remove(Component*);Component*        GetChild(int);Composite(string);~Composite(void);protected:Component*        nodes[];
};
Composite::Composite(string a_name):Component(a_name) {}
//+------------------------------------------------------------------+
//| participants > composite                                         |
//+------------------------------------------------------------------+
Composite::~Composite(void)
{int total = ArraySize(nodes);for (int i=0; i<total; i++){Component* i_node=nodes[i];if (CheckPointer(i_node)==1){delete i_node;}}
}
//+------------------------------------------------------------------+
//| participants > composite                                         |
//+------------------------------------------------------------------+
void Composite::Operation(void)
{Print(name);int total = ArraySize(nodes);for (int i=0; i<total; i++){nodes[i].Operation();}
}
//+------------------------------------------------------------------+
//| participants > composite                                         |
//+------------------------------------------------------------------+
void Composite::Add(Component *src)
{int size = ArraySize(nodes);ArrayResize(nodes,size+1);nodes[size] = src;
}
//+------------------------------------------------------------------+
//| participants > composite                                         |
//+------------------------------------------------------------------+
void Composite::Remove(Component *src)
{int find=-1;int total=ArraySize(nodes);for (int i=0; i<total; i++){if (nodes[i]==src){find=i;break;}}if (find>-1){ArrayRemove(nodes,find,1);}
}
//+------------------------------------------------------------------+
//| participants > composite                                         |
//+------------------------------------------------------------------+
Component* Composite::GetChild(int i)
{return nodes[i];
}
//+------------------------------------------------------------------+
//| interface for patterns                                           |
//+------------------------------------------------------------------+
interface ClientInterface 
{string Output(void);void Run(void);
};
//+------------------------------------------------------------------+
//| interface for patterns                                           |
//+------------------------------------------------------------------+
void Run(ClientInterface* client) //launches a pattern
{printf("---\n%s",client.Output()); //print pattern headerclient.Run(); //execute client collaborationsdelete client; //exit
}
// 通过组件接口操作组合中的对象
class Client:public ClientInterface
{public:string            Output(void);void              Run(void);
};
string Client::Output(void) {return __FUNCTION__;}
//+------------------------------------------------------------------+
//| collaborations                                                   |
//+------------------------------------------------------------------+
void Client::Run(void)
{Component* root=new Composite("root"); //make root//---make componentsComponent* branch1=new Composite(" branch 1");Component* branch2=new Composite(" branch 2");Component* leaf1=new Leaf("  leaf 1");Component* leaf2=new Leaf("  leaf 2");//---build treeroot.Add(branch1);root.Add(branch2);branch1.Add(leaf1);branch1.Add(leaf2);branch2.Add(leaf2);branch2.Add(new Leaf("  leaf 3"));//---checkprintf("tree:");root.Operation();//---change treeroot.Remove(branch1); //remove whole branch//---checkprintf("tree after removal of one branch:");root.Operation();//---finishdelete root;delete branch1;
}
//
void OnStart() 
{Run(new Composite::Client);
}
//+------------------------------------------------------------------+
//| output                                                           |
//+------------------------------------------------------------------+
//   Structural::Composite::Client::Output
//   tree:
//   root
//    branch 1
//     leaf 1
//     leaf 2
//    branch 2
//     leaf 2
//     leaf 3
//   tree after removal of one branch:
//   root
//    branch 2
//     leaf 2
//     leaf 3

这篇关于新版MQL语言程序设计:组合模式的原理、应用及代码实现的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


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

相关文章

nginx -t、nginx -s stop 和 nginx -s reload 命令的详细解析(结合应用场景)

《nginx-t、nginx-sstop和nginx-sreload命令的详细解析(结合应用场景)》本文解析Nginx的-t、-sstop、-sreload命令,分别用于配置语法检... 以下是关于 nginx -t、nginx -s stop 和 nginx -s reload 命令的详细解析,结合实际应

深入理解Go语言中二维切片的使用

《深入理解Go语言中二维切片的使用》本文深入讲解了Go语言中二维切片的概念与应用,用于表示矩阵、表格等二维数据结构,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧... 目录引言二维切片的基本概念定义创建二维切片二维切片的操作访问元素修改元素遍历二维切片二维切片的动态调整追加行动态

Linux下删除乱码文件和目录的实现方式

《Linux下删除乱码文件和目录的实现方式》:本文主要介绍Linux下删除乱码文件和目录的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux下删除乱码文件和目录方法1方法2总结Linux下删除乱码文件和目录方法1使用ls -i命令找到文件或目录

SpringBoot+EasyExcel实现自定义复杂样式导入导出

《SpringBoot+EasyExcel实现自定义复杂样式导入导出》这篇文章主要为大家详细介绍了SpringBoot如何结果EasyExcel实现自定义复杂样式导入导出功能,文中的示例代码讲解详细,... 目录安装处理自定义导出复杂场景1、列不固定,动态列2、动态下拉3、自定义锁定行/列,添加密码4、合并

mybatis执行insert返回id实现详解

《mybatis执行insert返回id实现详解》MyBatis插入操作默认返回受影响行数,需通过useGeneratedKeys+keyProperty或selectKey获取主键ID,确保主键为自... 目录 两种方式获取自增 ID:1. ​​useGeneratedKeys+keyProperty(推

Spring Boot集成Druid实现数据源管理与监控的详细步骤

《SpringBoot集成Druid实现数据源管理与监控的详细步骤》本文介绍如何在SpringBoot项目中集成Druid数据库连接池,包括环境搭建、Maven依赖配置、SpringBoot配置文件... 目录1. 引言1.1 环境准备1.2 Druid介绍2. 配置Druid连接池3. 查看Druid监控

Linux在线解压jar包的实现方式

《Linux在线解压jar包的实现方式》:本文主要介绍Linux在线解压jar包的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux在线解压jar包解压 jar包的步骤总结Linux在线解压jar包在 Centos 中解压 jar 包可以使用 u

c++ 类成员变量默认初始值的实现

《c++类成员变量默认初始值的实现》本文主要介绍了c++类成员变量默认初始值,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录C++类成员变量初始化c++类的变量的初始化在C++中,如果使用类成员变量时未给定其初始值,那么它将被

Qt使用QSqlDatabase连接MySQL实现增删改查功能

《Qt使用QSqlDatabase连接MySQL实现增删改查功能》这篇文章主要为大家详细介绍了Qt如何使用QSqlDatabase连接MySQL实现增删改查功能,文中的示例代码讲解详细,感兴趣的小伙伴... 目录一、创建数据表二、连接mysql数据库三、封装成一个完整的轻量级 ORM 风格类3.1 表结构

基于Python实现一个图片拆分工具

《基于Python实现一个图片拆分工具》这篇文章主要为大家详细介绍了如何基于Python实现一个图片拆分工具,可以根据需要的行数和列数进行拆分,感兴趣的小伙伴可以跟随小编一起学习一下... 简单介绍先自己选择输入的图片,默认是输出到项目文件夹中,可以自己选择其他的文件夹,选择需要拆分的行数和列数,可以通过