java设计模式之【组合模式】

总结:

1.组合模式适用于对树形结构的操作,比如递归检查每一个权限树、递归删除权限树等

2.抽象子节点时,比如例子1中 叶子结点(文件)和非叶子结点(目录)是有不一致的行为的,比如文件不能添加目录,像这种情况就要声明一个接口,1个叶子结点实现类和1个非叶子结点实现类来组合对象树形的数据结构。但是例子2中部门的行为是完全一致的,因此例子2算是组合模式的一个变种,吸收了其设计思想,但是实现更简洁!!!

3.天然适合与访问者模式搭配起来使用

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------

例1:实现文件目录和文件的树形结构

抽象类: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 nodeList = new ArrayList();//内部节点列表(包括文件和下级目录)
    //通过构造器为当前目录节点赋名
    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

例2:实现父子部门的树形结构

public class CompositePatternDemo {
	
	public static void main(String[] args) {
		Department leafDept1 = new Department("叶子部门1"); 
		Department leafDept2 = new Department("叶子部门2");
		Department leafDept3 = new Department("叶子部门3"); 
		
		Department subDept1 = new Department("子部门1");
		subDept1.getChildren().add(leafDept1);
		subDept1.getChildren().add(leafDept2);
		
		Department subDept2 = new Department("子部门2"); 
		subDept2.getChildren().add(leafDept3);
		
		Department parentDept = new Department("父部门");
		parentDept.getChildren().add(subDept1);
		parentDept.getChildren().add(subDept2);
		
		parentDept.remove();
		
		// 组合模式的第一要义,就是将树形结构的数据,用一个类,或者少数一两个类,就可以拼装成一棵树的形状
		// 组合模式的第二要义,就是直接对一个父级的数据执行某个操作,这个操作会直接递归调用所有下层的子数据的相关操作
		
		// 设计模式,重点,是思想,理解了思想,随便招式你怎么出,只要能将思想运用到实际业务场景中
		// 避免写出屎一样的代码,你就成功了
		// 如果你照搬设计模式去写,反而增加代码的复杂度
	}
	
	public static class Department {
		
		private String name;
		private List children = new ArrayList();
		
		public Department(String name) {
			super();
			this.name = name;
		}
		
		public String getName() {
			return name;
		}
		public void setName(String name) {
			this.name = name;
		}
		public List getChildren() {
			return children;
		}
		public void setChildren(List children) {
			this.children = children;
		}
		
		public void remove() {
			if(children.size() > 0) {
				for(Department child : children) {
					child.remove();
				}
			}
			System.out.println("删除部门【" + name + "】");  
		}
		
	}
	
}

 

运行结果:

删除部门【叶子部门1】
删除部门【叶子部门2】
删除部门【子部门1】
删除部门【叶子部门3】
删除部门【子部门2】
删除部门【父部门】

 

你可能感兴趣的:(java设计模式,java设计模式)