一,什么是组合模式

Composite 模式 也叫组合模式,是构造型的设计模式之一,通过递归手段来构造树形的对象结构,并可以通过一个对象来访问整个对象树

二,组合模式的结构

组合模式的角色和职责

Component : (树形结构的节点抽象)

  • 为所有的对象定义统一的接口,(公共属性,行为等的定义)
  • 提供管理子节点对象的接口方法
  • (选择)提供管理父节点对象的接口方法

Leaf : (树形结构的叶节点)

Composite: (树形结构的枝节点)

优点:

  1. 组合模式使得客户端代码可以一致地处理单个对象和组合对象,无须关心自己处理的是单个对象,还是组合对象,这简化了客户端代码;
  2. 更容易在组合体内加入新的对象,客户端不会因为加入了新的对象而更改源代码,满足“开闭原则”;

缺点:

  1. 设计较复杂,客户端需要花更多时间理清类之间的层次关系;
  2. 不容易限制容器中的构件;
  3. 不容易用继承的方法来增加构件的新功能;

组合模式分为透明式的组合模式和安全式的组合模式。

四:透明方式代码实现:

透明方式:在该方式中,由于抽象构件声明了所有子类中的全部方法,所以客户端无须区别树叶对象和树枝对象,对客户端来说是透明的。但其缺点是:树叶构件本来没有 Add()、Remove() 及 GetChild() 方法,却要实现它们(空实现或抛异常),这样会带来一些安全性问题。

Component

public interface IFile {/*** @Description: 显示文件夹的名称* @param:* @return: void**/public void display();/*** @Description: 添加* @param: []* @return: boolean**/public boolean add(IFile iFile);/*** @Description: 删除* @param: []* @return: boolean**/public boolean remove(IFile iFile);/*** @Description: 获得子节点* @param: []* @return: java.util.List<com.enjoy.cap26.IFile>**/public List<IFile> getChildren();}

Leaf

/*** @ClassName Files* @Description TODO* @Version 1.0**/
public class Files implements IFile{private String name;public Files(String name) {this.name = name;}@Overridepublic void display() {System.out.println(name);}@Overridepublic boolean add(IFile iFile) {return false;}@Overridepublic boolean remove(IFile iFile) {return false;}@Overridepublic List<IFile> getChildren() {return null;}
}

Composite

/*** @ClassName Folder* @Description TODO* @Version 1.0**/
public class Folder implements IFile{private String name;private List<IFile> children;public Folder(String name) {this.name = name;children = new ArrayList<IFile>();}@Overridepublic void display() {System.out.println(name);}@Overridepublic boolean add(IFile iFile) {return children.add(iFile);}@Overridepublic boolean remove(IFile iFile) {return  children.remove(iFile);}@Overridepublic List<IFile> getChildren() {return children;}
}

测试:

/*** @ClassName test* @Description TODO* @Version 1.0**/
public class Test {public static void main(String[] args) {//父节点Folder folder = new Folder("D:");//子节点 目录Folder javaFoder = new Folder("java");//子节点 helloworld.txtFiles  files = new Files("helloworld.txt");folder.add(javaFoder);folder.add(files);Folder sprFoder = new Folder("spring");Files files2 = new Files("springAop-api");javaFoder.add(sprFoder);javaFoder.add(files2);//子节点 目录Folder stuFoder = new Folder("学习");Files files1 = new Files("String.txt");folder.add(stuFoder);folder.add(files1);displayTree(folder,0);}/*** 使用递归* @param iFile* @param deep*/public static  void  displayTree(IFile iFile,int deep){for (int i = 0; i < deep;i++){System.out.print("--");}//显示自身名称iFile.display();List<IFile>  children = iFile.getChildren();for (IFile file : children) {if( file instanceof Files){for (int i = 0; i <= deep;i++){System.out.print("---");}file.display();}else{displayTree(file,deep+1);}}}}

五,安全方式

安全方式:在该方式中,将管理子构件的方法移到树枝构件中,抽象构件和树叶构件没有对子对象的管理方法,这样就避免了上一种方式的安全性问题,但由于叶子和分支有不同的接口,客户端在调用时要知道树叶对象和树枝对象的存在,所以失去了透明性。

Component

/*** @ClassName Articles* @Description 抽象构建* @Version 1.0**/
public interface Articles {/*** @Description: 计算* @param: []* @return: float* @Author: wuchao* @Date: 2020/6/26 20:31**/public float calculation();/*** @Description: 显示* @param: []* @return: void* @Author: wuchao* @Date: 2020/6/26 20:32**/public  void show();
}

leaf:

/*** @ClassName Goods* @Description 树叶构件* @Version 1.0**/
public class Goods implements  Articles{private String name;/*** 数量*/private int quantity;/*** 单价*/private float unitPrice;public Goods(String name, int quantity, float unitPrice) {this.name = name;this.quantity = quantity;this.unitPrice = unitPrice;}@Overridepublic float calculation() {return quantity*unitPrice;}@Overridepublic void show() {System.out.println(name+"(数量:"+quantity+",单价:"+unitPrice+"元)");}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getQuantity() {return quantity;}public void setQuantity(int quantity) {this.quantity = quantity;}public float getUnitPrice() {return unitPrice;}public void setUnitPrice(float unitPrice) {this.unitPrice = unitPrice;}
}

Composite

/*** @ClassName Bags* @Description TODO* @Version 1.0**/
public class Bags implements Articles{private String name;private List<Articles> list;public Bags(String name) {this.name = name;list = new ArrayList<Articles>();}@Overridepublic float calculation() {float s=0;for(Object obj:list){s+=((Articles)obj).calculation();}return s;}@Overridepublic void show() {for(Object obj:list) {((Articles)obj).show();}}/*** 新增对象* @param c*/public void add(Articles c) {list.add(c);}/*** 删除对象* @param c*/public void remove(Articles c) {list.remove(c);}/*** 获得list* @return*/public List<Articles> getChild(){return list;}
}

测试:

public class Test {public static void main(String[] args) {float s=0;Bags BigBag,mediumBag,smallRedBag,smallWhiteBag;Goods sp;BigBag=new Bags("大袋子");mediumBag=new Bags("中袋子");smallRedBag=new Bags("红色小袋子");smallWhiteBag=new Bags("白色小袋子");sp=new Goods("婺源特产",2,7.9f);smallRedBag.add(sp);sp=new Goods("婺源地图",1,9.9f);smallRedBag.add(sp);sp=new Goods("韶关香菇",2,68);smallWhiteBag.add(sp);sp=new Goods("韶关红茶",3,180);smallWhiteBag.add(sp);sp=new Goods("景德镇瓷器",1,380);mediumBag.add(sp);mediumBag.add(smallRedBag);sp=new Goods("李宁牌运动鞋",1,198);BigBag.add(sp);BigBag.add(smallWhiteBag);BigBag.add(mediumBag);System.out.println("您选购的商品有:");BigBag.show();s=BigBag.calculation();System.out.println("要支付的总价是:"+s+"元");}
}

六,组合模式的应用场景

  1. 在需要表示一个对象整体与部分的层次结构的场合。
  2. 要求对用户隐藏组合对象与单个对象的不同,用户可以用统一的接口使用组合结构中的所有对象的场合。

了解23种设计模式之组合模式相关推荐

  1. 在王者荣耀角度下分析面向对象程序设计B中23种设计模式之组合模式

    · 组合模式在王者荣耀中的应用 · 一.简述 王者荣耀有非常多的英雄,而且每一个不同的英雄也有其自己对应的皮肤.玩家可以根据需要购买不同的英雄皮肤,体验不同英雄皮肤在对局中的感受. 在本实例中,根据组 ...

  2. 23种设计模式之组合模式

    组合模式的定义 定义: 将对象组合成树形结构以表示 "部分-整体" 的层次结构,使得用户对单个对象和组合对象的使用具有一致性. 通俗的说, 就是实现了树形结构 通用类图如下: 其中 ...

  3. 23种设计模式——装饰者模式

    文章目录 23种设计模式--装饰者模式 1.装饰者模式概述 2.装饰者模式的结构 3.装饰者模式的实现 4.装饰者模式的应用场景 23种设计模式--装饰者模式 1.装饰者模式概述 背景 有些人为了早上 ...

  4. 【Go实现】实践GoF的23种设计模式:命令模式

    上一篇:[Go实现]实践GoF的23种设计模式:代理模式 简单的分布式应用系统(示例代码工程):https://github.com/ruanrunxue/Practice-Design-Patter ...

  5. 23种设计模式之命令模式和策略模式的区别

    文章目录 概述 命令模式 策略模式 相同点 总结 概述 命令模式和策略模式确实很相似,只是命令模式多了一个接收者(Receiver)角色.它们虽然同为行为类模式,但是两者的区别还是很明显的.策略模式的 ...

  6. 实践GoF的23种设计模式:建造者模式

    本文分享自华为云社区<[Go实现]实践GoF的23种设计模式:建造者模式>,作者: 元闰子. 简述 在程序设计中,我们会经常遇到一些复杂的对象,其中有很多成员属性,甚至嵌套着多个复杂的对象 ...

  7. 23种设计模式7_代理模式之一静态代理

    23种设计模式7_代理模式之一静态代理 1 基本介绍 代理模式:为其他对象提供一种代理以控制对这个对象的访问 代理模式也叫委托模式,它是一项基本设计技巧.许多其他的模式,如状态模式.策略模式.访问者模 ...

  8. 23种设计模式之代理模式

    文章目录 代理模式的定义与特点 代理模式的结构与实现 模式的结构 模式的实现 代理模式的应用场景 代理模式的应用实例 代理模式的扩展 代理模式分类 静态代理 动态代理 在有些情况下,一个客户不能或者不 ...

  9. 23种设计模式----中介者模式----行为型模式

    中介者模式 1.什么是中介者模式 2.中介者模式的角色 3.例子 3.1 项目结构 3.2 共同实体 3.3 抽象的中介者 3.4 抽象的被中介者 3.5 具体的中介者 3.6 具体的被中介者 3.7 ...

最新文章

  1. 提取指定的PDF表格保存到Excel
  2. Silverlight2 边学边练 之五 视频
  3. Nova 启动虚拟机流程解析
  4. Hyperopt 入门指南
  5. 嵌入式论文3000字_SCI英文论文一般多少字
  6. C++重载流插入运算符与流提取运算符
  7. 《网络安全原理与实践》一1.2 资产确定
  8. 数据结构链表代码_代码简介:链表数据结构如何工作
  9. 搜狐被SEC列入“预摘牌名单”!回应:不打算提出异议
  10. 5G 基站为何建得比 4G 多?
  11. Recursive Depth first search graph(adj matrix)
  12. 敏捷个人:免费下载【敏捷个人 –认识自我、管理自我 V0.2.pdf】
  13. MyBatis-Plus updateById方法更新不了空字符串/null解决方法
  14. 用计算机怎么把图片合成,利用电脑自带的将画图软件把两张图片拼成一张
  15. 我爱淘冲刺阶段站立会议2每天任务2
  16. 年轻人要明白,职场里不只有晋升
  17. thinkadmin上传与保存资源文件
  18. CPU 发热的几个可能原因
  19. 简单粗暴清理C盘办法
  20. python实现3d人物建模_一张图实现3D人脸建模!这是中科院博士生入选ECCV的新研究 | 开源...

热门文章

  1. 【编程实践】谈谈高质量代码的“6大支柱”
  2. Windows系统弹窗病毒
  3. AVS(AviSynth)的认识
  4. Android(java)学习笔记182:多媒体之撕衣服的案例
  5. previous_sibling和next_sibling的理解
  6. 粒度(granule)需要注意的地方
  7. 小程序流量全面爆发,谁会湾道超车
  8. 一物一码的好处是什么?恒修堂给你答案
  9. Python—入门例程(持续更新)
  10. 阿里云代码持续集成rdc思路