Java描述设计模式(10):组合模式
本文源码:GitHub·点这里 || GitEE·点这里
一、生活场景
1、文件系统
下图是常见的计算机文件系统的一部分。
文件系统是一个树结构,树上长有节点。树的节点有两种:
- 树枝节点
即文件夹,有内部树结构,在图中涂有颜色;
- 树叶节点
另一种是文件,即树叶节点,没有内部树结构。
2、打印文件树结构
public class C01_InScene {
public static void main(String[] args) {
File file = new File("F:\\tree") ;
fileTree(file, 0);
}
private static void fileTree(File file, int floor) {
// 判断是否存在
if (file.exists()) {
if (floor > 0) {
// 循环打空格
for (int i = 0; i < floor; i++) {
System.out.print(" ");
}
}
if (file.isDirectory()) {
System.out.println("+" + file.getName());
// 列出所有文件及文件夹
File[] files = file.listFiles();
if (null != files) {
// 循环递归
for (File dirFile : files) {
fileTree(dirFile, floor + 1);
}
}
} else {
System.out.println("-" + file.getName());
}
}
}
}
执行效果:+代表文件夹,-代表文件。
+tree
+dir1
+dir2
-dir2Leaf.txt
-leaf1.txt
-leaf2.txt
-OneLeaf.txt
-TwoLeaf.txt
3、组合模式描述
组合模式属于对象的结构模式,有时又叫做“部分——整体”模式。组合模式将对象组织到树结构中,可以用来描述整体与部分的关系。组合模式可以使客户端将单纯元素与复合元素同等看待。
二、组合模式-安全式
1、基础概念
安全式的组合模式要求管理聚集的方法只出现在树枝构件类中,而不出现在树叶构件类中。涉及到三个角色:
- 抽象构件(Component)角色
它给组合的对象定义出公共的接口及其默认行为,可以用来管理所有的子对象。组合对象通常把它所包含的子对象当做类型为Component的对象。在安全式的组合模式里,构件角色并不定义出管理子对象的方法,这一定义由树枝构件对象给出。
- 树叶构件(Leaf)角色
树叶对象是没有下级子对象的对象,定义出参加组合的原始对象的行为。
- 树枝构件(Composite)角色
代表参加组合的有下级子对象的对象。树枝构件类给出所有的管理子对象的方法,如add()、remove()以及getChild()。
2、模式图解
3、源代码实现
public class C02_Security_Model {
public static void main(String[] args) {
Composite root = new Composite("服装");
Composite composite1 = new Composite("男装");
Leaf manCoat = new Leaf("上衣");
Leaf manBottom = new Leaf("下衣");
composite1.addChild(manCoat);
composite1.addChild(manBottom);
Composite composite2 = new Composite("女装");
Leaf leaf1 = new Leaf("鞋子");
Leaf leaf2 = new Leaf("帽子");
root.addChild(leaf1);
root.addChild(leaf2);
root.addChild(composite1);
root.addChild(composite2);
root.printStruct("");
}
}
// 抽象构件角色类
interface Component {
/*
* 输出组件自身的名称
*/
void printStruct(String preStr);
}
// 树枝构件角色类
class Composite implements Component{
// 用来存储组合对象中包含的子组件对象
private List<Component> childComponents = new ArrayList<Component>();
// 输出对象的名称
private String name;
// 构造方法,传入组合对象的名字
public Composite (String name){
this.name = name;
}
/**
* 聚集管理方法,增加一个子构件对象
* @param child 子构件对象
*/
public void addChild(Component child){
childComponents.add(child);
}
/**
* 聚集管理方法,删除一个子构件对象
* @param index 子构件对象的下标
*/
public void removeChild(int index){
childComponents.remove(index);
}
/**
* 聚集管理方法,返回所有子构件对象
*/
public List getChild(){
return childComponents ;
}
/**
* 输出对象的自身结构
* @param preStr 前缀,主要是按照层级拼接空格,实现向后缩进
*/
@Override
public void printStruct(String preStr) {
//先输出自己
System.out.println(preStr+"+"+this.name);
//如果还包含有子组件,那么就输出这些子组件对象
if (this.childComponents != null){
//添加两个空格,表示向后缩进两个空格
preStr = preStr+" ";
//输出当前的子对象:使用函数递归的原理
for (Component c : childComponents) {
c.printStruct(preStr);
}
}
}
}
class Leaf implements Component{
// 输出叶子对象的名称
private String name;
// 构造方法,传入叶子对象的名称
public Leaf (String name){
this.name = name ;
}
/**
* 输出叶子对象的结构,叶子对象没有子对象,也就是输出叶子对象的名字
* @param preStr 前缀,主要是按照层级拼接的空格,实现向后缩进
*/
@Override
public void printStruct(String preStr) {
System.out.println(preStr+"-"+name);
}
}
- 输出结果
+服装
-鞋子
-帽子
+男装
-上衣
-下衣
+女装
三、组合模式-透明式
1、概念图解
与安全式的组合模式不同的是,透明式的组合模式要求所有的具体构件类,不论树枝构件还是树叶构件,均符合一个固定接口。
2、源代码实现
public class C03_Transparent_Model {
public static void main(String[] args) {
Component1 root = new Composite1("服装");
Component1 c1 = new Composite1("男装");
Component1 c2 = new Composite1("女装");
Component1 leaf1 = new Leaf1("衬衫");
Component1 leaf2 = new Leaf1("夹克");
Component1 leaf3 = new Leaf1("裙子");
Component1 leaf4 = new Leaf1("套装");
root.addChild(c1);
root.addChild(c2);
c1.addChild(leaf1);
c1.addChild(leaf2);
c2.addChild(leaf3);
c2.addChild(leaf4);
root.printStruct("");
}
}
abstract class Component1 {
/**
* 输出组件自身的名称
*/
public abstract void printStruct(String preStr);
// 聚集管理方法,增加一个子构件对象
public void addChild(Component1 child){
/**
* 缺省实现,抛出异常,因为叶子对象没有此功能
* 或者子组件没有实现这个功能
*/
throw new UnsupportedOperationException("对象不支持此功能");
}
// 聚集管理方法,删除一个子构件对象
public void removeChild(int index){
/**
* 缺省实现,抛出异常,因为叶子对象没有此功能
* 或者子组件没有实现这个功能
*/
throw new UnsupportedOperationException("对象不支持此功能");
}
// 聚集管理方法,返回所有子构件对象
public List<Component1> getChild(){
/**
* 缺省实现,抛出异常,因为叶子对象没有此功能
* 或者子组件没有实现这个功能
*/
throw new UnsupportedOperationException("对象不支持此功能");
}
}
class Composite1 extends Component1 {
// 用来存储组合对象中包含的子组件对象
private List<Component1> childComponents = new ArrayList<Component1>();
// 输出对象名称
private String name ;
public Composite1 (String name){
this.name = name;
}
/**
* 聚集管理方法,增加一个子构件对象
* @param child 子构件对象
*/
public void addChild(Component1 child){
childComponents.add(child);
}
/**
* 聚集管理方法,删除一个子构件对象
* @param index 子构件对象的下标
*/
public void removeChild(int index){
childComponents.remove(index);
}
// 聚集管理方法,返回所有子构件对象
public List<Component1> getChild(){
return childComponents ;
}
/**
* 输出对象的自身结构
* @param preStr 前缀,主要是按照层级拼接空格,实现向后缩进
*/
@Override
public void printStruct(String preStr) {
// 首先输出自己名称
System.out.println(preStr+"+"+this.name);
// 如果还包含有子组件,那么就输出这些子组件对象
preStr = preStr + " ";
if (this.childComponents != null) {
// 添加两个空格,表示向后缩进
for (Component1 c : childComponents) {
////递归输出每个子对象
c.printStruct(preStr);
}
}
}
}
class Leaf1 extends Component1 {
private String name;
public Leaf1 (String name){
this.name = name;
}
/**
* 输出叶子对象的结构,叶子对象没有子对象,也就是输出叶子对象的名字
* @param preStr 前缀,主要是按照层级拼接的空格,实现向后缩进
*/
@Override
public void printStruct(String preStr) {
System.out.println(preStr+"-"+name);
}
}
四、JDK中应用
1、HashMap结构图
2、分层结构
- interface Map
- class AbstractMap implements Map
- HashMap extends AbstractMap implements Map
- interface Map.Entry
- Node implements Map.Entry
3、源代码
- 存储叶子节点
public V put(K var1, V var2) {
return this.putVal(hash(var1), var1, var2, false, true);
}
final V putVal(int var1, K var2, V var3, boolean var4, boolean var5) {
HashMap.Node[] var6 = this.table;
.......
}
- 存储树枝节点
public void putAll(Map<? extends K, ? extends V> var1) {
this.putMapEntries(var1, true);
}
五、源代码地址
GitHub·地址
https://github.com/cicadasmile/model-arithmetic-parent
GitEE·地址
https://gitee.com/cicadasmile/model-arithmetic-parent
Java描述设计模式(10):组合模式的更多相关文章
- C#设计模式(10)——组合模式(Composite Pattern)
一.引言 在软件开发过程中,我们经常会遇到处理简单对象和复合对象的情况,例如对操作系统中目录的处理就是这样的一个例子,因为目录可以包括单独的文件,也可以包括文件夹,文件夹又是由文件组成的,由于简单对象 ...
- C#设计模式(10)——组合模式(Composite Pattern)(转)
一.引言 在软件开发过程中,我们经常会遇到处理简单对象和复合对象的情况,例如对操作系统中目录的处理就是这样的一个例子,因为目录可以包括单独的文件,也可以包括文件夹,文件夹又是由文件组成的,由于简单对象 ...
- C#设计模式(10)——组合模式
一.概念 组合模式有时候又叫做部分-整体模式,它使我们树型结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以向处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元素的内部结构解耦. 二.组 ...
- 基于JAVA的设计模式之组合模式
概念 将所有对象组合成一种树形结构,有分支节点.叶子节点,分支节点可以有自己的子节点,子节点可以是分支节点.叶子节点,可以进行增删的操作,而叶子节点不可以.比如文件夹就是一个分支节点,而文件就是一个叶 ...
- JavaScript设计模式之----组合模式
javascript设计模式之组合模式 介绍 组合模式是一种专门为创建Web上的动态用户界面而量身制定的模式.使用这种模式可以用一条命令在多个对象上激发复杂的或递归的行为.这可以简化粘合性代码,使其更 ...
- c++设计模式15 --组合模式
今天研究了一下设计模式15 组合模式 本人是菜鸟一枚,所以一开始完全不懂组合究竟是什么意思.先上图一张,树形结构图: 文档说,如果想做出这样的结构,通常考虑组合模式.那是为什么呢?现在让我们看一下组合 ...
- 乐在其中设计模式(C#) - 组合模式(Composite Pattern)
原文:乐在其中设计模式(C#) - 组合模式(Composite Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 组合模式(Composite Pattern) 作者:weba ...
- C#设计模式:组合模式(Composite Pattern)
一,C#设计模式:组合模式(Composite Pattern) using System; using System.Collections.Generic; using System.Linq; ...
- 设计模式之组合模式——Java语言描述
组合模式又叫做部分整体模式,适用于把一组相似的对象当作一个单一的对象.组合模式依据树形结构来组合对象,用来表示部分以及整体层次 介绍 意图 将对象组合成树形结构以表示"部分-整体" ...
随机推荐
- CCF-CSP题解 201703-3 Markdown
要求实现简易的Markdown到Html格式的转换. 主要就是字符串处理.以空行划分各个区块,区块内部字符的输出用一个\(print\_buf\)实现,至于强调和超链接的嵌套,则可以递归实现. 注意用 ...
- 《MySQL数据库》MySQL数据库安装(linux)
1. 下载安装包: 百度网盘:链接: https://pan.baidu.com/s/1toGl8O9gMBpDWn0mHWwFyg 提取码: i51g 官网下载:https://dev.mysql ...
- 使用littlefs-fuse在PC端调试littlefs文件系统
背景 littlefs是arm面向嵌入式设备推出的一款掉电安全的小型文件系统,具有抗掉电,动态磨损均衡,RAM/ROM需求少等特点,具体介绍可见 https://github.com/ARMmbed/ ...
- 原创 Hive left join 技巧总结
根据工作中经验总结出来 left join 常用的 使用注意点: A Left join B on A.id = B.id 第一种情况: 如果 A 表 ...
- python基础之字符串讲解(上)
字符串 字符串是 Python 中最常用的数据类型.我们可以使用引号('或者")来创建字符串. 创建字符串很简单,只要为变量分配一个值即可.For example: 为str输入一个变量,p ...
- 【目录】Cocos2d-x系列
1.Cocos2d-x的坐标系统 2.Cocos2d-x 点击菜单按键居中放大(无需修改底层代码) 3.发布Cocos2d-x的PC端程序 4.Cocos2d-x游戏实例<忍者飞镖>之对象 ...
- JAVA杂记
写在前面:期末考试要来了,对于一个暑假自学了几天JAVA之后一个学期划水的人来说现在就是踏上了JAVA预习之路.下面是自己xjb记的东西,主要是根据老师给的流程图总结的自己认为需要的一些零碎的小知识, ...
- swoole简介
swoole是PHP的扩展,又不是一个普通的扩展.普通的扩展只是提供一个库函数.而swoole扩展在运行后会接管PHP的控制权,进入事件循环.当IO事件发生后,swoole会自动回调指定的PHP函数. ...
- Pull Request 工作流——更高效的管理代码
目录 Pull Request 工作流--更高效的管理代码 1.问题 2.解决方案 3.Git分支流管理代码具体实施 3.1本地分支操作管理 3.1.1查看分支 3.1.2创建分支 3.1.3切换分支 ...
- Pyhton中变量和数据类型
一.变量 Python中变量的命名规则: 1.变量名只能包含数字.字母.下划线,且不能用数字打头. eg: message_1是对的但1_message就是错误的 2.变量名不能包含空格. 3.在变量 ...