一、上下文及问题
将对象组合成树型结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
二、常见场景
1、如果你想表示对象的部分-整体层次结构,可以选用组合模式,把整体和部分的操作统一起来,是的层次结构实现更简单,从外部来使用这个层次结构也容易。
2、如果你希望统一滴使用组合结构中的所有对象,可以选用组合模式,这正是组合模式提供的主要功能。
比如管理品类,人员组织结构。
三、解决方法
1、安全型的组合模式
父类只定义公共的方法,客户端得区分哪些是部分哪些是整体,各自的操作方法有不同,之所以说是安全,是因为,没有把特殊子类不支持的方法放到公用类里头,不会引发操作不支持。
2、透明的组合模式
父类在公共方法里头,定义了管理方法,对客户端来说是透明的,它不需要区分谁是整体谁是部分,但是可能引用操作不安全,比如调用的方法,特殊子类并不支持。
四、抽象模型
五、代码实例
1、安全型
抽象类
public abstract class BranchComponent { public String getName() { throw new UnsupportedOperationException(); } public String getDiscription() { throw new UnsupportedOperationException(); } public void display() { throw new UnsupportedOperationException(); }}
子类1
public class BranchLeaf extends BranchComponent { private String name; private String discription; public BranchLeaf(String name, String discription) { this.name = name; this.discription = discription; } public void display() { System.out.printf("\t%s: %s\n", name, discription); } public String getName() { return name; } public String getDiscription() { return discription; }
子类2
public class BranchComposite extends BranchComponent { private String name; private String discription; private ListchildrenBranch; public BranchComposite(String name, String discription) { this.name = name; this.discription = discription; childrenBranch = new ArrayList (); } public void display() { System.out.printf("%s: %s\n", name, discription); for (BranchComponent child : childrenBranch) { child.display(); } } public String getName() { return name; } public String getDiscription() { return discription; } public void add(BranchComponent child) { childrenBranch.add(child); } public void remove(BranchComponent child) { childrenBranch.remove(child); } public BranchComponent getChild(int index) { return childrenBranch.get(index); }}
客户端
public class TestDrive { public static void main(String[] args) { BranchComposite china = new BranchComposite("CN", "China Branch"); BranchComposite shanghai = new BranchComposite("Sh", "Shanghai Branch"); BranchLeaf huangpu = new BranchLeaf("Hp", "Huangpu Branch"); BranchLeaf yangpu = new BranchLeaf("Yp", "Yangpu Branch"); BranchLeaf pudong = new BranchLeaf("Pd", "Pudong Branch"); BranchComposite beijing = new BranchComposite("Bj", "Beijing Branch"); BranchLeaf dongcheng = new BranchLeaf("Dc", "Dongcheng Branch"); BranchLeaf xicheng = new BranchLeaf("Xc", "Xicheng Branch"); BranchLeaf haidian = new BranchLeaf("Hd", "Haidian Branch"); shanghai.add(huangpu); shanghai.add(yangpu); shanghai.add(pudong); beijing.add(dongcheng); beijing.add(xicheng); beijing.add(haidian); china.add(shanghai); china.add(beijing); System.out.println("Displaying the head bank information"); display(china); System.out.println("\nDisplaying Shanghai bank branch information"); display(shanghai); System.out.println("\nDisplaying Pudong bank branch information in Shanghai"); display(pudong); } private static void display(BranchComponent branch) { branch.display(); }}
2、透明型
抽象类
public abstract class BranchComponent { public String getName() { throw new UnsupportedOperationException(); } public String getDiscription() { throw new UnsupportedOperationException(); } public void display() { throw new UnsupportedOperationException(); } public void add(BranchComponent child) { throw new UnsupportedOperationException(); } public void remove(BranchComponent child) { throw new UnsupportedOperationException(); } public BranchComponent getChild(int index) { throw new UnsupportedOperationException(); }}
子类1
public class BranchLeaf extends BranchComponent { private String name; private String discription; public BranchLeaf(String name, String discription) { this.name = name; this.discription = discription; } public void display() { System.out.printf("\t%s: %s\n", name, discription); } public String getName() { return name; } public String getDiscription() { return discription; }}
子类2
public class BranchComposite extends BranchComponent { private String name; private String discription; private ListchildrenBranch; public BranchComposite(String name, String discription) { this.name = name; this.discription = discription; childrenBranch = new ArrayList (); } public void display() { System.out.printf("%s: %s\n", name, discription); for (BranchComponent child : childrenBranch) { child.display(); } } public String getName() { return name; } public String getDiscription() { return discription; } public void add(BranchComponent child) { childrenBranch.add(child); } public void remove(BranchComponent child) { childrenBranch.remove(child); } public BranchComponent getChild(int index) { return childrenBranch.get(index); }}
客户端
public class TestDrive { public static void main(String[] args) { BranchComposite china = new BranchComposite("CN", "China Branch"); BranchComposite shanghai = new BranchComposite("Sh", "Shanghai Branch"); BranchLeaf huangpu = new BranchLeaf("Hp", "Huangpu Branch"); BranchLeaf yangpu = new BranchLeaf("Yp", "Yangpu Branch"); BranchLeaf pudong = new BranchLeaf("Pd", "Pudong Branch"); BranchComposite beijing = new BranchComposite("Bj", "Beijing Branch"); BranchLeaf dongcheng = new BranchLeaf("Dc", "Dongcheng Branch"); BranchLeaf xicheng = new BranchLeaf("Xc", "Xicheng Branch"); BranchLeaf haidian = new BranchLeaf("Hd", "Haidian Branch"); shanghai.add(huangpu); shanghai.add(yangpu); shanghai.add(pudong); beijing.add(dongcheng); beijing.add(xicheng); beijing.add(haidian); china.add(shanghai); china.add(beijing); System.out.println("Displaying the head bank information"); display(china); System.out.println("\nDisplaying Shanghai bank branch information"); display(shanghai); System.out.println("\nDisplaying Pudong bank branch information in Shanghai"); display(pudong); } private static void display(BranchComponent branch) { branch.display(); }}
3、组织结构实例
Tree
public class Tree{ private TreeNode root; private Map > treeMap = new HashMap >(); public Tree(T rootData){ root = new TreeNode (); root.setData(rootData); } public Tree(List lists){ constructFromList(lists); } public void constructFromList(List lists){ for(T obj:lists){ if(treeMap.containsKey(obj.getId()) == false){ treeMap.put(obj.getId(),new TreeNode (obj)); } } for(T obj:lists){ TreeNode currentNode = treeMap.get(obj.getId()); TreeNode parent = treeMap.get(obj.getParentId()); if(obj.getParentId() == null || obj.getParentId() == 0){ this.root = currentNode; }else{ //add to parent if(currentNode.getParent() == null){ currentNode.setParent(parent); } parent.addChild(currentNode); } } System.out.println(ReflectTool.getObjectSize(treeMap, SizeEnum.M)); } public TreeNode findById(Integer id){ TreeNode treeNode = treeMap.get(id); return treeNode; } //递归获取下属实例 public void findNodeLeaves(TreeNode node,List collects){ if(node == null) return; if(node.getData().getIsEmployee()){ collects.add(node.getData());// System.out.println(node.getData()); }else{ System.out.println(node.getData()); } if(node.getChildren().size() == 0) return; for(TreeNode cld : node.getChildren()){ findNodeLeaves(cld,collects); } }}
TreeNode
public class TreeNode{ private T data; private TreeNode parent; private Set > children = new HashSet >(); public TreeNode() { } public TreeNode(T data) { this.data = data; } public void addChild(TreeNode child){ children.add(child); } public T getData() { return data; } public void setData(T data) { this.data = data; } public TreeNode getParent() { return parent; } public void setParent(TreeNode parent) { this.parent = parent; } public Set > getChildren() { return children; }}
客户端
public class TreeNodeTest { @Test public void testTree() throws IOException { URL url = Resources.getResource("Depts.json"); String text = Resources.toString(url, Charsets.UTF_8); List