【设计模式系列】--组合模式
在前面的博文中,小编介绍了三个工厂模式,三世同堂,各司其职,各有千秋,今天我们继续来学习设计模式的相关知识,今天这篇博文,我们继续来学习设计模式的相关知识,今天这篇博文小编主要和小伙伴们来学习组合
在前面的博文中,小编介绍了三个工厂模式,三世同堂,各司其职,各有千秋,今天我们继续来学习设计模式的相关知识,今天这篇博文,我们继续来学习设计模式的相关知识,今天这篇博文小编主要和小伙伴们来学习组合模式。小编会从什么是组合模式、组合模式的结构图、组合模式的角色和职责以及结合相关的deom来进行讲解。
一、什么是组合模式
组合模式,英文名字叫Composite,是结构型的设计模式,通过递归手段来构造树形的对象结构,并可以通过一个对象来访问整个对象树,将对象组合成树形结构以表示“部分-整体”的层次结构,组合模式使得用户对单个对象和组合对象的使用具有一致性。
二、组合模式的结构图
三、组合模式的角色和职责
Component(树形结构的节点抽象)
为所有的对象定义统一的接口(公共属性,行为等的定义)
提供管理子节点对象的接口方法
[可选]提供管理父节点对象的接口方法
Leaf(树形结构的叶结点)
Component的实现子类
Composite(树形结构的枝节点)
Component的实现子类
接着,小编举一个简单的例子,小伙伴们看下面这幅图
上面两幅图片我们可以看作是一个文件结构,对于这样的结构我们称之为树形结构,在程杰老师的大话设计模式一书中,我们知道可以通过调用某个方法来遍历整棵树,当我们找到某个叶子节点后,就可以对叶子节点进行相关的操作,我们可以将这棵树理解成一个大容器,容器里面包含很多的成员对象,这些成员对象既可以是容器对象也可以是叶子对象,但是由于容器对象和叶子对象在功能上面的区别,使得我们在使用的过程中要区分容器对象和叶子对象,但是这样会给用户带来不必要的麻烦,对于客户而言,始终希望能够一致的对待容器对象和叶子对象,这就是组合模式的设计动机,组合模式定义了如何将容器对象和叶子对象进行递归组合,使得客户在使用的过程中无须进行区分,可以对他们进行一直的处理。接着小编通过一个简单的demo讲解组合模式如何在项目中使用,希望可以帮助到有需要的小伙伴,不足之处,还请小伙伴多多指教`(*&_&*)&。
四、组合模式小demo
新建项目Composite项目,新建接口IFile也就是文件节点的抽象相当于设计模式结构图中的Component,编写相关代码,如下所示:
import java.util.L
* 文件节点抽象(是文件和目录的父类)
* @author Flower
public interface IFile {
//显示文件或文件夹的名称
public void display();
public boolean add(IFile file);
public boolean remove(IFile file);
//获得子节点
public List geChild();
接着新建File,相当于结构图中的Leaf,具体代码如下所示:
import java.util.L
public class File implements IFile {
public File (String name){
this.name =
public void display() {
// TODO Auto-generated method stub
public boolean add(IFile file) {
// TODO Auto-generated method stub
public boolean remove(IFile file) {
// TODO Auto-generated method stub
public List geChild() {
// TODO Auto-generated method stub
新建类Folder,相当于结构图中的Composite,编写相关的代码部分,如下所示:
import java.util.ArrayL
import java.util.L
public class Folder implements IFile {
private List
public Folder(String name){
this.name =
children= new ArrayList();
public void display() {
System.out.println(name);
public boolean add(IFile file) {
return children.add(file);
public boolean remove(IFile file) {
return children.remove(file);
public List geChild() {
编写客户端的代码,新建类MainClass,具体代码如下所示:
import java.util.L
public class MainClass {
public static void main(String[] args){
Folder rootFolder = new Folder("C:");
//beifeng目录
Folder beifengFolder = new Folder("beifeng");
//beifeng.txt文件
File beifengFile = new File("beifeng.txt");
rootFolder.add(beifengFile);
rootFolder.remove(beifengFile);
displayTree(rootFolder);
private static void displayTree(IFile rootFolder) {
rootFolder.display();
List children = rootFolder.geChild();
//遍历子数
for(IFile file:children){
if(file instanceof File){
file.display();
displayTree(file);
运行,如下所示:
小伙伴们可能觉得这样看起来层次结构不是很清晰,我们来完善一下我们的MainClass部分,如下所示:
import java.util.L
public class MainClass {
public static void main(String[] args){
Folder rootFolder = new Folder("C:");
//beifeng目录
Folder beifengFolder = new Folder("beifeng");
//beifeng.txt文件
File beifengFile = new File("beifeng.txt");
rootFolder.add(beifengFolder);
rootFolder.add(beifengFile);
//ibeifeng目录
Folder ibeifengFolder = new Folder("ibeifeng");
File ibeifengFile = new File("ibeifeng.txt");
beifengFolder.add(ibeifengFolder);
beifengFolder.add(ibeifengFile);
displayTree(rootFolder);
private static void displayTree(IFile rootFolder) {
//显示自身的名称
rootFolder.display();
//获得子树
List children = rootFolder.geChild();
//遍历子数
for(IFile file : children){
if(file instanceof File){
file.display();
displayTree(file);
运行一下,效果如下所示:
这样层次结构就比较深了,接着我们加上层次结构,完善MainClass的代码部分,如下所示:
import java.util.L
public class MainClass {
public static void main(String[] args){
Folder rootFolder = new Folder("C:");
//beifeng目录
Folder beifengFolder = new Folder("beifeng");
//beifeng.txt文件
File beifengFile = new File("beifeng.txt");
rootFolder.add(beifengFolder);
rootFolder.add(beifengFile);
//ibeifeng目录
Folder ibeifengFolder = new Folder("ibeifeng");
File ibeifengFile = new File("ibeifeng.txt");
beifengFolder.add(ibeifengFolder);
beifengFolder.add(ibeifengFile);
displayTree(rootFolder,0);
private static void displayTree(IFile rootFolder,int deep) {
for(int i = 0;i children = rootFolder.geChild();
//遍历子数
for(IFile file : children){
if(file instanceof File){
for(int i =0;i 运行效果如下所示:
我们再来添加一个,完善代码,如下所示: import java.util.L
public class MainClass {
public static void main(String[] args){
Folder rootFolder = new Folder("C:");
//beifeng目录
Folder beifengFolder = new Folder("beifeng");
//beifeng.txt文件
File beifengFile = new File("beifeng.txt");
rootFolder.add(beifengFolder);
rootFolder.add(beifengFile);
//ibeifeng目录
Folder ibeifengFolder = new Folder("ibeifeng");
File ibeifengFile = new File("ibeifeng.txt");
beifengFolder.add(ibeifengFolder);
beifengFolder.add(ibeifengFile);
Folder iibeifengFolder = new Folder("iibeifeng");
File iibeifengFile = new File("iibeifeng.txt");
ibeifengFolder.add(iibeifengFolder);
ibeifengFolder.add(iibeifengFile);
displayTree(rootFolder,0);
private static void displayTree(IFile rootFolder,int deep) {
for(int i = 0; i & i++) {
System.out.print("--");
//显示自身的名称
rootFolder.display();
//获得子树
List children = rootFolder.geChild();
//遍历子数
for(IFile file : children){
if(file instanceof File){
for(int i = 0; i &= i++) {
System.out.print("--");
file.display();
displayTree(file,deep+1);