原创作品,可以转载,但是请标注出处地址http://www.cnblogs.com/V1haoge/p/6489827.html

  组合模式,就是在一个对象中包含其他对象,这些被包含的对象可能是终点对象(不再包含别的对象),也有可能是非终点对象(其内部还包含其他对象,或叫组对象),我们将对象称为节点,即一个根节点包含许多子节点,这些子节点有的不再包含子节点,而有的仍然包含子节点,以此类推。很明显,这是树形结构,终结点叫叶子节点,非终节点(组节点)叫树枝节点,第一个节点叫根节点。同时也类似于文件目录的结构形式:文件可称之为终节点,目录可称之为非终节点(组节点)。

1、我们首先来看一个目录结构的普通实现:

目录节点:Noder

 import java.util.ArrayList;
import java.util.List;
/**
* 目录节点
* 包含:
* 1、目录名
* 2、下级文件列表
* 3、下级目录列表
* 4、新增文件方法
* 5、新增目录方法
* 6、显示下级内容方法
*/
public class Noder {
String nodeName;//目录名
//通过构造器为目录命名
public Noder(String nodeName){
this.nodeName = nodeName;
}
List<Noder> nodeList = new ArrayList<Noder>();//目录的下级目录列表
List<Filer> fileList = new ArrayList<Filer>();//目录的下级文件列表
//新增下级目录
public void addNoder(Noder noder){
nodeList.add(noder);
}
//新增文件
public void addFiler(Filer filer){
fileList.add(filer);
}
//显示下级目录及文件
public void display(){
for(Noder noder:nodeList){
System.out.println(noder.nodeName);
noder.display();//递归显示目录列表
}
for(Filer filer:fileList){
filer.display();
}
}
}

文件节点:Filer

 /**
* 文件节点
* 文件节点是终节点,无下级节点
* 包含:
* 1、文件名
* 2、文件显示方法
*/
public class Filer {
String fileName;//文件名
public Filer(String fileName){
this.fileName = fileName;
}
//文件显示方法
public void display(){
System.out.println(fileName);
}
}

测试类:Clienter

 import java.io.File;

 public class Clienter {
public static void createTree(Noder node){
File file = new File(node.nodeName);
File[] f = file.listFiles();
for(File fi : f){
if(fi.isFile()){
Filer filer = new Filer(fi.getAbsolutePath());
node.addFiler(filer);
}
if(fi.isDirectory()){
Noder noder = new Noder(fi.getAbsolutePath());
node.addNoder(noder);
createTree(noder);//使用递归生成树结构
}
}
}
public static void main(String[] args) {
Noder noder = new Noder("E://ceshi");
createTree(noder);//创建目录树形结构
noder.display();//显示目录及文件
}
}

运行结果:

E:\ceshi\目录1
E:\ceshi\目录1\目录3
E:\ceshi\目录1\文件2.txt
E:\ceshi\目录2
E:\ceshi\目录2\文件3.txt
E:\ceshi\文件1.txt

2、组合模式

  从上面的代码中可以看出,我们分别定义了文件节点对象与目录节点对象,这是因为文件与目录之间的操作不同,文件没有下级节点,而目录可以有下级节点,但是我们能不能这么想:既然文件与目录都是可以作为一个节点的下级节点而存在,那么我们可不可以将二者抽象为一类对象,虽然二者的操作不同,但是我们可以在实现类的方法实现中具体定义,比如文件没有新增下级节点的方法,我们就可以在文件的这个方法中抛出一个异常,不做具体实现,而在目录中则具体实现新增操作。显示操作二者都有,可以各自实现。而且由于我们将文件与目录抽象为一个类型,那么结合多态我们可以进行如下实现:

抽象类:Node

 /**
* 将文件与目录统一看作是一类节点,做一个抽象类来定义这种节点,然后以其实现类来区分文件与目录,在实现类中分别定义各自的具体实现内容
*/
public abstract class Node {
protected String name;//名称
//构造器赋名
public Node(String name){
this.name = name;
}
//新增节点:文件节点无此方法,目录节点重写此方法
public void addNode(Node node) throws Exception{
throw new Exception("Invalid exception");
}
//显示节点:文件与目录均实现此方法
abstract void display();
}

文件实现类:Filter

 /**
* 实现文件节点
*/
public class Filer extends Node {
//通过构造器为文件节点命名
public Filer(String name) {
super(name);
}
//显示文件节点
@Override
public void display() {
System.out.println(name);
}
}

目录实现类:Noder

 import java.util.*;
/**
* 实现目录节点
*/
public class Noder extends Node {
List<Node> nodeList = new ArrayList<Node>();//内部节点列表(包括文件和下级目录)
//通过构造器为当前目录节点赋名
public Noder(String name) {
super(name);
}
//新增节点
public void addNode(Node node) throws Exception{
nodeList.add(node);
}
//递归循环显示下级节点
@Override
void display() {
System.out.println(name);
for(Node node:nodeList){
node.display();
}
}
}

测试类:Clienter

 import java.io.File;

 public class Clienter {
public static void createTree(Node node) throws Exception{
File file = new File(node.name);
File[] f = file.listFiles();
for(File fi : f){
if(fi.isFile()){
Filer filer = new Filer(fi.getAbsolutePath());
node.addNode(filer);
}
if(fi.isDirectory()){
Noder noder = new Noder(fi.getAbsolutePath());
node.addNode(noder);
createTree(noder);//使用递归生成树结构
}
}
}
public static void main(String[] args) {
Node noder = new Noder("E://ceshi");
try {
createTree(noder);
} catch (Exception e) {
e.printStackTrace();
}
noder.display();
}
}
E://ceshi
E:\ceshi\文件1.txt
E:\ceshi\目录1
E:\ceshi\目录1\文件2.txt
E:\ceshi\目录1\目录3
E:\ceshi\目录2
E:\ceshi\目录2\文件3.txt

  从上述实现中可以看出:所谓组合模式,其实说的是对象包含对象的问题,通过组合的方式(在对象内部引用对象)来进行布局,我认为这种组合是区别于继承的,而另一层含义是指树形结构子节点的抽象(将叶子节点与数枝节点抽象为子节点),区别于普通的分别定义叶子节点与数枝节点的方式。

3、组合模式应用场景

  这种组合模式正是应树形结构而生,所以组合模式的使用场景就是出现树形结构的地方。比如:文件目录显示,多及目录呈现等树形结构数据的操作。

Java设计模式之《组合模式》及应用场景的更多相关文章

  1. java设计模式之组合模式

    组合模式 组合模式,将对象组合成树形结构以表示“部分-整体”的层次结构,组合模式使得用户对单个对象和组合对象的使用具有一致性.掌握组合模式的重点是要理解清楚 “部分/整体” 还有 ”单个对象“ 与 & ...

  2. Java设计模式应用——组合模式

    组合模式实际上是一种树形数据结构.以windows目录系统举例,怎么样用java语言描述一个文件夹? 定义一个文件夹类,文件夹类中包含若干个子文件类和若干个文件类. 进一步抽象,把文件夹和文件都看做节 ...

  3. java设计模式5.组合模式、门面模式、享元模式、桥接模式

    组合模式 在面向对象的语言中,树结构有着巨大的威力,一个基于继承的类型的等级结构便是一个数结构,一个基于合成的对象结构也是一个数结构.组合模式将部分与整体的关系用树结构表示出来,使得客户端把一个个单独 ...

  4. JAVA设计模式之组合模式(composite)

    组合模式:树状结构专用模式 代码如下: package com.srr.dp.composite; import java.util.ArrayList; import java.util.List; ...

  5. 老和尚给小和尚讲故事引发了Java设计模式:组合模式

    目录 示例 组合模式 定义 意图 主要解决问题 优缺点 安全式和透明式的组合模式 安全式的合成模式的结构 透明式的合成模式的结构 老和尚和小和尚的故事 示例 有一个绘图系统,可以描绘各种图形,假设现在 ...

  6. Java设计模式之模板模式及使用场景

    模板模式,顾名思义,就是通过模板拓印的方式. 定义模板,就是定义框架.结构.原型.定义一个我们共同遵守的约定. 定义了模板,我们的剩余工作就是对其进行充实.丰润,完善它的不足之处. 定义模板采用抽象类 ...

  7. Java设计模式之代理模式(静态代理和JDK、CGLib动态代理)以及应用场景

    我做了个例子 ,需要可以下载源码:代理模式 1.前言: Spring 的AOP 面向切面编程,是通过动态代理实现的, 由两部分组成:(a) 如果有接口的话 通过 JDK 接口级别的代理 (b) 如果没 ...

  8. Java设计模式——装饰者模式

    JAVA 设计模式 装饰者模式 用途 装饰者模式 (Decorator) 动态地给一个对象添加一些额外的职责.就增加功能来说,Decorator 模式相比生成子类更为灵活. 装饰者模式是一种结构式模式 ...

  9. JAVA设计模式--装饰器模式

    装饰器模式 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装饰 ...

  10. 折腾Java设计模式之访问者模式

    博客原文地址:折腾Java设计模式之访问者模式 访问者模式 Represent an operation to be performed on the elements of an object st ...

随机推荐

  1. IOS Cell 重影

    效果:重影 原因: 多次创建控件元素 解决:在initWithStyle中进行初始化元素

  2. iOS 之 事件响应者链

    响应者链表示一系列的响应者对象.事件被交由第一个响应者对象处理,如果第一个响应者不处理,事件就沿着响应者链向上传递,交由下一个响应者(Next responder). View->ViewCon ...

  3. 【翻译】使用Visual Studio创建Asp.Net Core MVC (一)

    This tutorial will teach you the basics of building an ASP.NET Core MVC web app using Visual Studio ...

  4. 无法打开登录 'ASPState' 中请求的数据库。登录失败。

    问题: 无法打开登录 'ASPState' 中请求的数据库.登录失败.用户 'WH\Administrator' 登录失败. 解决方法: (启动SQL Server Agent服务) 从本系统中找到: ...

  5. 如何估算网站日承受最大访问PV

    每个老板或客户都会问架构师这个问题. 你设计的网站能承受多大的日访问量. 程序员都会拍胸脯说出一个心理最大数字.说的时候很有信心.其实这个数字大多是猜的.作为一个理性的程序员怎么能用猜呢? 这里就介绍 ...

  6. MyBatis 的Mapper中有小于号的处理

    <![CDATA[ select * from person t where t.birthday < #{birthday} ]]> 也可以进行转义: < < 小于号 ...

  7. WebRTC音视频引擎研究(2)--VoiceEngine音频编解码器数据结构以及参数设置

    1.VoiceEngine Codec数据结构 WebRTC中,用一个结构体struct CodecInst表示特定的音频编解码器对象: struct CodecInst { int pltype;  ...

  8. css基础详解(1)

    css讲解 声明 1:这里的文字都是我从我自己csdn账号拷贝过来,是本人学习总结的结晶,所以请尊重本作品.2:如要要转载本文章,则要说明文字的出处.3:如有哪里不对或者哪里还不够完善欢迎大家指出. ...

  9. IE6浏览器常见的bug及其修复方法

    IE6不支持min-height,解决办法使用css hack: .target { min-height: 100px; height: auto !important; height: 100px ...

  10. linux pagecache与内存占用

    实验环境 CentOS Linux release 7.3.1611 (Core)  3.10.0-514.6.1.el7.x86_64   一.概念介绍      linux系统中通常使用free命 ...