网站添加文字大小/企业建站公司热线电话
系列文章
可跳转到下面链接查看下表所有内容https://blog.csdn.net/handsomethefirst/article/details/138226266?spm=1001.2014.3001.5501文章浏览阅读2次。系列文章大全https://blog.csdn.net/handsomethefirst/article/details/138226266?spm=1001.2014.3001.5501
目录
系列文章
1.简介
2.简单工厂模式
2.1 简介
2.1.1 组成结构
2.1.2 优点和缺点
2.1.3 应用场景
2.2 代码案例
2.2.1 主要步骤
2.2.2 代码
3.工厂方法模式
3.1简介
3.1.1 组成结构
3.1.2 优点和缺点
3.1.3 应用场景
3.2 代码案例
3.2.1 主要步骤
3.2.2 代码
4.抽象工厂模式
4.1简介
4.1.1 组成结构
4.1.2 优点和缺点
4.2 代码案例
4.2.1 主要步骤
4.2.2 代码
5.区别
1.简介
工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,即定义一个用于创建对象的接口,让子类决定应该实例化哪个类,使类的实例化延迟到子类。 也可以这样理解,
工厂模式可以分为三类:
1.简单工厂模式(Simple Factory)
2.工厂方法模式(Factory Method)
3.抽象工厂模式(Abstract Factory)
2.简单工厂模式
2.1 简介
简单工厂模式是通过一个工厂类将所有对象的创建封装起来,通过传入不同的参数,工厂负责创建不同的具体对象。
建立对象的类是工厂,被建立的对象是产品,使用产品的人无需关心这个产品是怎样生产的,这样便降低了模块之间的耦合。
2.1.1 组成结构
1.工厂类:用来创建所有产品,通过传入的type不同,从而创建不同的产品。例如:本节案例代码中的Factory类。
2.抽象产品类:它一般是具体产品继承的父类或者实现的接口。例如:本节案例代码中的Car类。
3.具体产品类:此类继承抽象产品类,自工厂类所创建的对象就是此角色的实例。例如:本节案例代码中的CarA类和CarB类。
特点:一个工厂生产所有的具体产品。
2.1.2 优点和缺点
优点:
1.将所有对象的创建集合到了一个工厂类中,客户端只需要调用工厂类的接口,传入不同的参数,而无需关注具体对象的创建过程。
2.可以通过工厂类创建不同的对象,而客户端无需改动,实现了客户端和具体所有对象的解耦,提高了代码的灵活性。
缺点:
1.每新增一个产品,则需要修改工厂类的逻辑,违反了开闭原则。
2.当产品足够多的时候,代码会过于臃肿,不利于维护。
2.1.3 应用场景
1.需要根据不同的参数类型创建不同的对象时。
2.2 代码案例
当前代码场景:
我们现在一个工厂要生产车型A和车型B
2.2.1 主要步骤
第一步:创建抽象产品类Car和创建抽象run函数
第二步:创建具体产品类车型A(CarA),实现其抽象run函数。
第三步:创建具体产品类车型B(CarB),实现其抽象run函数
第四步:创建工厂类Factory,并书写根据不同参数创建不同车型的createCar方法。
第五步:客户端(此例是main.cpp调用)创建工厂类对象,通过传递不同的参数,工厂创建不同的对象并返回给客户。
2.2.2 代码
// 抽象产品类
class Car
{public:virtual void run() = 0; // 抽象共同接口string cartype;
};// 具体产品类:车A
class CarA : public Car
{public:CarA(){cartype = "A 车";}virtual void run(){std::cout << "this is cartype = " << cartype << endl;}
};// 具体产品类:车B
class CarB : public Car
{public:CarB(){cartype = "B 车";}virtual void run(){std::cout << "this is cartype = " << cartype << endl;}
};// 工厂类
class Factory
{
public:Car *createCar(int type){switch (type){case CAR_TYPE_A:return new CarA();break;case CAR_TYPE_B:return new CarB();break;default:return nullptr;break;}}
};int main()
{Factory *mFactory = new Factory(); // c创建工厂类Car *acar = mFactory->createCar(CAR_TYPE_A); // 根据具体的参数创建对应的对象,此处是父类指针指向子类对象Car *bcar = mFactory->createCar(CAR_TYPE_B);acar->run();bcar->run();// 注意析构delete acar;delete bcar;delete mFactory;return 0;
}
3.工厂方法模式
3.1简介
工厂方法模式在简单工厂模式的基础上,去掉了简单工厂模式中的创建所有对象的方法,并提供了一个抽象生产产品的接口,并使其它可以被子类继承。这样在简单工厂模式里集中在工厂方法上的压力可以由工厂方法模式里不同的工厂子类来分担。
简单工厂模式的特点是一个工厂只生产所有产品,而工厂方法模式则是一个工厂只生产一个产品,这样当生产产品的时候,只需要确定是哪个工厂即可。
3.1.1 组成结构
1.抽象工厂类:是具体工厂类的父类,其包含一个具体工厂类必须实现的抽象接口。例如:本节案例代码的Factory类,抽象接口是createCar函数。
2.具体工厂类:对应其具体产品,用以创建对应的具体产品的对象。例如:本节案例代码的工厂A和工厂B,工厂A负责生产车型A, 工厂B负责生产车型B。
3.抽象产品类:它是具体产品继承的父类。例如:本节案例代码的Car类。
4.具体产品类:具体工厂类所创建的对象就是此类的实例。例如:本节案例代码的车型A类和车型B类。
3.1.2 优点和缺点
优点:
1.当需要增加新的工厂和产品的时候,可以不用更改现有代码,增加了代码的可扩展性,将对象的创建和使用进行了解耦。
缺点:
1.当产品种类过多时,由于每一种产品都需要实现一个工厂类,增加代码复杂性。
3.1.3 应用场景
当只有一类产品时。同时客户端需要生成不同的对象。
3.2 代码案例
此时场景为:
A工厂生产车型A,B工厂生产车型B
3.2.1 主要步骤
第一步:创建抽象产品类(Car类)。
第二步:创建抽象产品类的两个子类(CarA类和CarB类),其子类是具体产品类。
第三步:创建抽象工厂类(Factory类),并提供生产对象的抽象接口。
第四步:创建两个具体工厂类,一个是生产CarA的工厂类,一个是生产CarB的工厂类,并实现抽象方法,创建不同的产品对象。
第五步:客户端(此例是main.cpp调用)创建不同的工厂类对象,从而创建出多个不同的产品对象。
3.2.2 代码
// 抽象产品类
class Car
{public:virtual void run() = 0; // 抽象共同接口string cartype;
};// 具体产品类:车A
class CarA : public Car
{public:CarA(){cartype = "A 车";}virtual void run(){std::cout << "this is cartype = " << cartype << endl;}
};// 具体产品类:车B
class CarB : public Car
{public:CarB(){cartype = "B 车";}virtual void run(){std::cout << "this is cartype = " << cartype << endl;}
};// 抽象工厂类
class Factory
{
public:virtual Car *createCar() = 0;
};// 具体工厂类:工厂A(对应产品A)
class FactoryA : public Factory
{
public:virtual Car *createCar(){return new CarA();}
};
// 具体工厂类:工厂B(对应产品B)
class FactoryB : public Factory
{
public:virtual Car *createCar(){return new CarB();}
};int main()
{Factory *mFactoryA = new FactoryA(); // 创建具体工厂类ACar *acar = mFactoryA->createCar(); // 根据具体的工厂类创建对应的对象,此处是父类指针指向子类对象acar->run();Factory *mFactoryB = new FactoryB(); // 创建具体工厂类BCar *bcar = mFactoryB->createCar(); // 根据具体的工厂类创建对应的对象,此处是父类指针指向子类对象bcar->run();// 注意析构delete acar;delete bcar;delete mFactoryA;delete mFactoryB;return 0;
}
4.抽象工厂模式
之前的工厂方法模式一个工厂只生产一个产品,而在实际生活中,通过一个工厂会生产多种产品,比如:车的组成需要轮胎和方向盘,那么当出现多个产品的时候,便需要使用抽象工厂模式。
4.1简介
提供一个创建一系列相关或相互依赖的对象接口,而无需指定它们的具体类。其实抽象工厂模式就是多个工厂方法模式,只是因为工厂方法是一个工厂只创建一个产品,而抽象工厂模式是一个工厂创建多个产品。
4.1.1 组成结构
抽象工厂类:是具体工厂类的父类,其内部定义了创建多个产品对象的抽象接口,必须由具体工厂类实现。
例如:本节代码案例中的Factory类,抽象接口为createTire和createWheel。
具体工厂类:对应其具体产品,用以创建对应的具体产品的对象。
例如:本节代码案例中的 具体工厂(工厂白色)和具体工厂(工厂黑色)。
抽象产品类:定义了产品的共同接口,具体的产品类必须实现这个接口。工厂模式会由多个产品,因此抽象产品类也是多个。
例如:本节代码案例中的第一个抽象产品类(轮胎)和第二个抽象产品类(方向盘)。
具体产品类:是抽象工厂模式中具体创建的对象。
例如:本节代码案例中的白轮胎和黑轮胎,白方向盘和黑方向盘。
4.1.2 优点和缺点
优点:
创建产品族,将一系列的产品族,统一到一起进行创建
缺点:
扩展困难,当产品族中有新产品,比如新增发动机产品时,需要修改抽象工厂的接口。
4.2 代码案例
现在场景为:
白色工厂需要生产白色轮胎和白色方向盘。
黑色工厂需要生产黑色轮胎和黑色方向盘。
白色系列产品由白色工厂统一管理。
黑色系列产品由黑色工厂统一管理。
4.2.1 主要步骤
第一步:创建第一个抽象产品类(轮胎类)。
第二步:创建第一个抽象产品类的两个子类(白轮胎类和黑轮胎类),其子类是具体产品类。
第三步:创建第二个抽象产品类(方向盘类)。
第四步:创建第二个抽象产品类的两个子类(白方向盘类和黑方向盘类),其子类是具体产品类。
第五步:创建抽象工厂类(Factory类),并提供生产所有对象的两个抽象接口。
第六步:创建两个具体工厂类,一个是生产白色产品的白色工厂类,一个是生产黑色产品的白色工厂类,并实现两个抽象方法,创建不同的产品对象。
第七步:客户端(此例是main.cpp调用)创建不同的工厂类对象,从而创建出多个不同的产品对象。
4.2.2 代码
// 第一个抽象产品类:轮胎
class Tire
{public:virtual void whcihtype() = 0;string Tiretype;
};// 第一个抽象产类的第一个具体产品类:白轮胎
class WhiteTire : public Tire
{public:WhiteTire(){Tiretype = "白色轮胎";}virtual void whcihtype(){std::cout << "this is Tiretype = " << Tiretype << endl;}
};// 第一个抽象产类的第二个具体产品类:黑轮胎
class BlackTire : public Tire
{public:BlackTire(){Tiretype = "黑色轮胎";}virtual void whcihtype(){std::cout << "this is Tiretype = " << Tiretype << endl;}
};// 第二个抽象产品类:方向盘
class Wheel
{
public:virtual void whcihtype() = 0;string Wheeltype;
};// 第二个抽象产类的第一个具体产品类:白色方向盘
class WhiteWheel : public Wheel
{public:WhiteWheel(){Wheeltype = "白色方向盘";}virtual void whcihtype(){std::cout << "this is Wheeltype = " << Wheeltype << endl;}
};// 第二个抽象产类的第二个具体产品类:黑色方向盘
class BlackWheel : public Wheel
{public:BlackWheel(){Wheeltype = "黑色方向盘";}virtual void whcihtype(){std::cout << "this is Wheeltype = " << Wheeltype << endl;}
};// 抽象工厂类
class Factory
{
public:virtual Tire *createTire() = 0; // 抽象接口virtual Wheel *createWheel() = 0;
};// 具体工厂类:工厂白色(对应生产白色轮胎和白色方向盘)
class FactoryWhite : public Factory
{
public:virtual Tire *createTire(){return new WhiteTire(); // 生产白轮胎}virtual Wheel *createWheel(){return new WhiteWheel(); // 生产白方向盘}
};// 具体工厂类:工厂黑色(对应生产黑色轮胎和黑色方向盘)
class FactorBlock : public Factory
{
public:virtual Tire *createTire(){return new BlackTire(); // 生产黑轮胎}virtual Wheel *createWheel(){return new BlackWheel(); // 生产黑方向盘}
};int main()
{Factory *mFactoryWhite = new FactoryWhite(); // 创建具体工厂类:工厂白色Tire *mWhiteTire = mFactoryWhite->createTire(); // 创建白色轮胎mWhiteTire->whcihtype();Wheel *mWhiteWheel = mFactoryWhite->createWheel(); // 创建白色方向盘mWhiteWheel->whcihtype();Factory *mFactoryBlock = new FactorBlock(); // 创建具体工厂类:工厂黑色Tire *mBlockTire = mFactoryBlock->createTire(); // 创建黑色轮胎mBlockTire->whcihtype();Wheel *mBlockWheel = mFactoryBlock->createWheel(); // 创建黑色方向盘mBlockWheel->whcihtype();// 注意析构delete mFactoryWhite;delete mWhiteTire;delete mWhiteWheel;delete mFactoryBlock;delete mBlockTire;delete mBlockWheel;return 0;
}
5.区别
简单工厂模式:
一个抽象产品类,可以派生出多个具体产品类。
无抽象工厂类,只有一个工厂类,此工厂类负责生产所有产品。
工厂方法模式:
一个抽象产品类,可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类只能创建一个具体产品类的实例。
抽象工厂模式:
多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类可以创建多个具体产品类的实例。
总结:
抽象产品类:工厂方法模式和简单工厂模式都只有一个抽象产品类,而抽象工厂模式有多个。
具体产品类:工厂方法模式和简单工厂模式都只能有一个抽象产品类派生出多个具体产品类,而抽象工厂模式可以从多个抽象产品类派生出多个具体产品类。
抽象工厂类:工厂方法模式和抽象工厂模式都有一个抽象工厂类,而简单工厂模式没有。
具体工厂类:简单工厂模式只有一个工厂类,而工厂方法模式和抽象工厂模式可以有多个具体工厂类。工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。
相关文章:

【设计模式】【创建型模式】【02工厂模式】
系列文章 可跳转到下面链接查看下表所有内容https://blog.csdn.net/handsomethefirst/article/details/138226266?spm1001.2014.3001.5501文章浏览阅读2次。系列文章大全https://blog.csdn.net/handsomethefirst/article/details/138226266?spm1001.2014.3001.5501 目录 系…...

FPGA设计中的流水线 -分割大的计算电路可以更快的处理数据。
FPGA(现场可编程门阵列)设计中的流水线优化是一种提高设计性能的技术,它通过将设计分解为多个阶段或步骤来实现。每个阶段可以并行执行,从而提高整体的吞吐量和效率。以下是流水线优化的一些关键概念和作用: 意思&…...

GNU/Linux - U-BOOT的GPIO command
在嵌入式Linux开发中,先运行的是u-boot,然后再加载Linux内核。 启动时如果设置了u-boot等待时间,在等待时间内,按任意键就会进入u-boot命令行环境。 在u-boot命令行环境下,可以使用gpio命令来操作GPIO。 Synopsis gpi…...

35.UART(通用异步收发传输器)-RS232(2)
(1)RS232接收模块visio框图: (2)接收模块Verilog代码编写: /* 常见波特率: 4800、9600、14400、115200 在系统时钟为50MHz时,对应计数为: (1/4800) * 10^9 /20 -1 10416 …...

OpenLayers学习笔记-点位聚合
需求 用户点击行政区划等操作后,从后台获取区域内的点位数据,在地图上聚合显示。用户手动取消聚合,点位直接渲染在地图上。 实现过程 使用后台返回的点位数据,通过new ol.source.Vector({features})创建矢量数据源。使用new ol.source.Cluster({source})创建聚合标注数据…...

flutter实现语言的国际化
目录 前言 一、GetX实现国际化(推荐) 1.安装Getx 2.创建国际化的文件 3.使用国际化字符串 4.配置GetMaterialApp 5.更改语言 6.系统语言 编辑 7.原生工程配置 1.iOS工程配 1.打开iOS工程,在Project的info里面添加语言 2.创建String File文件 2.andr…...

服务端正常启动了,但是客户端请求不到
服务端正常启动了,但是客户端请求不到有哪些原因?如何排查? 如果客户端请求的接口没有响应,排查的方式: 检查接口IP地址是否正确,ping一下接口地址。 检查被测接口端口号是否正确,可以在本机Telnet接口的IP和端口号…...

鸿蒙开发 -本地数据库操作
// 1导入模块 import relationalStore from @ohos.data.relationalStore;export class AthUserDbManager{//2.获取RdbStore实例,要注意的是,此处的getContext(this)用于获取应用上下文:getcreatDbtable(dbname:string){//配置数据库信息:const STORE_CONFIG :relationalStor…...

主机安全-进程、命令攻击与检测
目录 概述反弹shell原理nc/dev/xxx反弹shell下载不落地反弹Shell各种语言反弹shell linux提权sudosuid提权mysql提权 Dnslog参考 概述 本文更新通过在主机(不含容器)上直接执行命令或启动进程来攻击的场景。检测方面以字节跳动的开源HIDS elkeid举例。每…...

FPGA FIR fdatool filter designer MATLAB
位数问题 fdatool 先确定输入信号的位宽,比如17位在fdatool中,选set quantization parameters 选input/output 设置input word length 为17bit(not confirmed) fir compiler implementation 注意: 当设置输入位宽为16位时,ip核…...

水表数字识别2:Pytorch DBNet实现水表数字检测(含训练代码和数据集)
水表数字识别2:Pytorch DBNet实现水表数字检测(含训练代码和数据集) 目录 水表数字识别2:Pytorch DBNet实现水表数字检测(含训练代码和数据集) 1.前言 2. 水表数字识别的方法 3. 水表数字识别数据集 4. 水表数字分割模型训练 (1&#x…...

Windows 点云生成二维栅格图 [附C++完整代码实现]
点云压缩-2D栅格图 一、点云压缩(二维栅格图)二、算法流程三、代码实现四、结果可视化一、点云压缩(二维栅格图) 点云压缩:点云是海量点的集合,其数据量通常非常庞大。直接存储这些未经压缩的点云数据会消耗大量的存储空间,特别是在处理大规模的点云数据时,这个问题变得…...

SpringBoot结合ip2region实现博客评论显示IP属地
你好呀,我是小邹。 在现代的Web应用中,特别是博客和论坛类网站,为用户提供地理定位服务(如显示用户所在地理位置)可以极大地增强用户体验。本文将详细探讨如何使用Java和相关技术栈来实现在博客评论中显示用户的地址信…...

设计模式使用场景实现示例及优缺点(行为型模式——策略模式)
在遥远的王国里,有三个重要的角色:国王策略模式、他的皇家顾问算法家族,以及年轻的骑士接口。国王策略模式统治着整个王国,他的职责是确保每一个编程问题都能找到最合适的解决方案。 有一天,王国遇到了一场危机。编程王…...

ReactRouter v6升级的步骤
React Router v6 引入了一个 Routes 组件,它有点像 Switch ,但功能要强大得多。与 Switch 相比, Routes 的主要优势在于: <Routes> 中的所有 <Route> 和 <Link> 都是相对的。这导致在 <Route path> 和 &…...

【JVM实战篇】内存调优:内存问题诊断+案例实战
文章目录 诊断内存快照在内存溢出时生成内存快照MAT分析内存快照MAT内存泄漏检测的原理支配树介绍如何在不内存溢出情况下生成堆内存快照?MAT查看支配树MAT如何根据支配树发现内存泄漏 运行程序的内存快照导出和分析快照**大文件的处理** 案例实战案例1:…...

专业条码二维码扫描设备和手机二维码扫描软件的区别?
条码二维码技术已广泛应用于我们的日常生活中,从超市结账到公交出行,再到各类活动的入场验证,条码二维码的便捷性不言而喻,而在条码二维码的扫描识别读取过程中,专业扫描读取设备和手机二维码扫描软件成为了两大主要工…...

基于嵌入式Linux的高性能车载娱乐系统设计与实现 —— 融合Qt、FFmpeg和CAN总线技术
随着汽车智能化的发展,车载娱乐系统已成为现代汽车的标配。本文介绍了一个基于Linux的车载娱乐系统的设计与实现过程。该系统集成了音视频娱乐、导航、车辆信息显示等功能,旨在提供安全、便捷、丰富的驾驶体验。 1. 项目概述 随着汽车智能化的发展&…...

探索IP形象设计:快速掌握设计要点
随着市场竞争的加剧,越来越多的企业开始关注品牌形象的塑造和推广。在品牌形象中,知识产权形象设计是非常重要的方面。在智能和互联网的趋势下,未来的知识产权形象设计可能会更加关注数字和社交网络。通过数字技术和社交媒体平台,…...

泛微Ecology8明细表对主表赋值
文章目录 [toc]1.需求及效果1.1 需求1.2 效果2.思路与实现3.结语 1.需求及效果 1.1 需求 在明细表中的项目经理,可以将值赋值给主表中的项目经理来作为审批人员 1.2 效果 在申请人保存或者提交后将明细表中的人名赋值给主表中对应的值2.思路与实现 在通过js测…...

opencv—常用函数学习_“干货“_5
目录 十五、图像分割 简单阈值分割 (threshold) 自适应阈值分割 (adaptiveThreshold) 颜色范围分割 (inRange) 分水岭算法 (watershed) 泛洪填充 (floodFill) GrabCut算法 (grabCut) 距离变换 (distanceTransform) 最大稳定极值区域检测 (MSER) 均值漂移滤波 (pyrMean…...

JAVA零基础学习1(CMD、JDK、环境变量、变量和键盘键入、IDEA)
JAVA零基础学习1(CMD、JDK、环境变量、变量和键盘键入、IDEA) CMD常见命令配置环境变量JDK的下载和安装变量变量的声明和初始化声明变量初始化变量 变量的类型变量的作用域变量命名规则示例代码 键盘键入使用 Scanner 类读取输入步骤示例代码 常用方法处…...

Redis的安装配置及IDEA中使用
目录 一、安装redis,配置redis.conf 1.安装gcc 2.将redis的压缩包放到指定位置解压 [如下面放在 /opt 目录下] 3.编译安装 4.配置redis.conf文件 5.开机自启 二、解决虚拟机本地可以连接redis但是主机不能连接redis 1.虚拟机网络适配器网络连接设置为桥接模式…...

ubuntu 物理内存爆炸而不使用虚拟内存的问题
ubuntu 物理内存不足时有时候会不去使用虚拟内存,让虚拟内存空闲,而直接关闭占用内存的进程,如果在进行模型测试或训练时,就会导致训练或测试进程被杀死。 1. 修改 swappiness: cat /proc/sys/vm/swappiness sudo sysc…...

Python实现音频均衡和降噪
使用librosa库来读取音频文件,音频处理是一个复杂过程,这里只是简单的进行降噪和均衡。 import librosa import soundfile as sf def improve_audio_quality(input_file, output_file): # 读取音频文件 audio, sample_rate librosa.load(input_…...

【JavaScript 算法】贪心算法:局部最优解的构建
🔥 个人主页:空白诗 文章目录 一、贪心算法的基本概念贪心算法的适用场景 二、经典问题及其 JavaScript 实现1. 零钱兑换问题2. 活动选择问题3. 分配问题 三、贪心算法的应用四、总结 贪心算法(Greedy Algorithm)是一种逐步构建解…...

Azcopy Sync同步Azure文件共享
文章目录 Azcopy Sync同步文件共享一、工作原理二、安装 AzCopy在 Windows 上在 Linux 上 三、资源准备1. 创建源和目标 Azure 存储账户2. 创建源和目标文件共享3. 确定路径4. 生成源和目的存储账户的共享访问签名(SAS)令牌配置权限示例生成的 URL 四、A…...

单例模式 饿汉式和懒汉式的区别
单例模式(Singleton Pattern)是设计模式中最简单、最常见、最容易实现的一种模式。它确保一个类仅有一个实例,并提供一个全局访问点。单例模式主要有两种实现方式:饿汉式(Eager Initialization)和懒汉式&am…...

Python中的模块和包的定义以及如何在Python中导入和使用它们
在Python中,模块(Module)和包(Package)是组织代码以便重用和共享的基本单元。它们使得Python代码更加模块化,易于管理和维护。 模块(Module) 模块是一个包含Python代码的文件&…...

设计模式使用场景实现示例及优缺点(结构型模式——组合模式)
结构型模式 组合模式(Composite Pattern) 组合模式使得用户对单个对象和组合对象的使用具有一致性。 有时候又叫做部分-整体模式,它使我们树型结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以像处理简单元…...