第十四讲:组合模式

组合模式的核心是树,数据结构里面的树.

接口:Component.Component是斜写的,在UML里面斜写就表示是一个抽象类.add()增加节点,remove()移除节点,getChild()获得它的子节点.

Component可以是抽象类,也可以是一个接口,Leaf是叶子,Composite是组合.不管你是树叶还是节点你都是实现了Component接口.


组合模式的核心:可以通过一个对象访问整个对象树.


组合模式很好理解.

Component:组件,节点.

Leaf:叶子节点  Composite:子节点/枝节点.

叶子节点是最终的了,不会再包含其他节点了.

枝节点还可能有其他节点. 

递归的过程一定要清楚,首先是递,然后才归.然后再递再归.

C:
--beifeng
----ibeifeng
------iibeifeng
------iibeifeng.txt
----ibeifeng.txt
--beifeng.txt


import java.util.List;

/**
 * 文件节点抽象(是文件和目录的父类)
 * @author zhongzh
 *
 */
//组合模式有两种,一种是透明模式,IFile是一个接口,IFile定义的方法File必须实现.但是File不能add()、remove()和getChild()
//IFile公开了,File必须实现,这是一种透明的.
//还有一种是安全模式.把add()、remove()和getChild()方法放到子类里面去做,父类不做.我这个接口里面不声明出来.因为关系到File.
//这就是安全模式.但是对外界IFile就不透明了.外界调用IFile的时候不能看到add()等方法了,透明模式的话File不得不实现实现add()这些方法

public interface IFile {
     //private String name;
    //显示文件或者文件夹的名称
    public void display();
    
    //添加   管理子节点对象的接口方法
    public boolean add(IFile ifile);
    
    //移除    管理子节点对象的接口方法
    public boolean remove(IFile ifile);
    
    //获得子节点  管理子节点对象的接口方法
    public List<IFile> getChild();
    
}
import java.util.ArrayList;
import java.util.List;


public class Folder implements IFile{
   private String name;
   private List<IFile> children;//有一个pool包含文件或者是目录.
    public Folder(String name) {
    super();
    this.name = name;
    children = new ArrayList<IFile>();//线性表
}

    @Override
    public void display() {
        // TODO Auto-generated method stub
        System.out.println(name);
    }

    @Override
    public boolean add(IFile ifile) {
        // TODO Auto-generated method stub
        return children.add(ifile);
    }

    @Override
    public boolean remove(IFile ifile) {
        // TODO Auto-generated method stub
        return children.remove(ifile);
    }

    @Override
    public List<IFile> getChild() {
        // TODO Auto-generated method stub
        return children;
    }
    
}
import java.util.List;

//文件  不可能再包含其他的文件了  相当于UML图的Leaf
public class File implements IFile{
   private String name;
   
   
    public File(String name) {
    super();
    this.name = name;
}

    @Override
    public void display() {
        // TODO Auto-generated method stub
        System.out.println(name);
    }

    @Override
    public boolean add(IFile ifile) {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public boolean remove(IFile ifile) {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public List<IFile> getChild() {
        // TODO Auto-generated method stub
        return null;
        
    }

}
import java.util.Iterator;
import java.util.List;
//核心是displayTree()

public class MainClass {
     public static void main(String[] args) {
        //C盘
    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);
    }
     
     public static void displayTree(IFile rootFolder,int deep){//你必须把根目录传给它,它才能一节一节的往下走
         for(int i=0;i<deep;i++){//为什么这里不加等号,而下面for循环加等号.
             //因为下面for循环打印文件名称是必须把--打印出来.
             //而目录的话是放到下一次循环才打印的--,而目录的话层次结构已经加1了,所以这里是<
             System.out.print("--");
         }
         
         
         
         //显示一棵树,遍历一棵树
         //递归的概念
         
         //显示自身的名称
         rootFolder.display();
         //获得子树
         List<IFile> children  = rootFolder.getChild();//children是一棵树,因为children底下可能还有其他的目录或者文件.
         //遍历子树
         for (IFile iFile : children) {
            //递归的概念,重新调用displayTree(IFile rootFolder).
             if(iFile instanceof File){//是文件的话.
                 for(int i=0;i<=deep ;i++){
                     System.out.print("--");                     
                 }
                 
                 iFile.display();
             } else{//不是一个文件就是一个目录.
                 //displayTree(iFile);
                 displayTree(iFile,deep+1);
             }
        }
     }
     
     
}
原文地址:https://www.cnblogs.com/ZHONGZHENHUA/p/6740601.html