將對象組合成樹型結構以表示「部分-總體」的層次結構。組合模式使得用戶對單個對象和組合對象的使用具備一致性。java
一、若是你想表示對象的部分-總體層次結構,能夠選用組合模式,把總體和部分的操做統一塊兒來,是的層次結構實現更簡單,從外部來使用這個層次結構也容易。node
二、若是你但願統一滴使用組合結構中的全部對象,能夠選用組合模式,這正是組合模式提供的主要功能。json
好比管理品類,人員組織結構。安全
父類只定義公共的方法,客戶端得區分哪些是部分哪些是總體,各自的操做方法有不一樣,之因此說是安全,是由於,沒有把特殊子類不支持的方法放到公用類裏頭,不會引起操做不支持。this
父類在公共方法裏頭,定義了管理方法,對客戶端來講是透明的,它不須要區分誰是總體誰是部分,可是可能引用操做不安全,好比調用的方法,特殊子類並不支持。
url
抽象類spa
public abstract class BranchComponent { public String getName() { throw new UnsupportedOperationException(); } public String getDiscription() { throw new UnsupportedOperationException(); } public void display() { throw new UnsupportedOperationException(); } }
子類1code
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; }
子類2orm
public class BranchComposite extends BranchComponent { private String name; private String discription; private List<BranchComponent> childrenBranch; public BranchComposite(String name, String discription) { this.name = name; this.discription = discription; childrenBranch = new ArrayList<BranchComponent>(); } 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(); } }
抽象類
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 List<BranchComponent> childrenBranch; public BranchComposite(String name, String discription) { this.name = name; this.discription = discription; childrenBranch = new ArrayList<BranchComponent>(); } 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(); } }
Tree
public class Tree<T extends TreeObject> { private TreeNode<T> root; private Map<Integer,TreeNode<T>> treeMap = new HashMap<Integer, TreeNode<T>>(); public Tree(T rootData){ root = new TreeNode<T>(); root.setData(rootData); } public Tree(List<T> lists){ constructFromList(lists); } public void constructFromList(List<T> lists){ for(T obj:lists){ if(treeMap.containsKey(obj.getId()) == false){ treeMap.put(obj.getId(),new TreeNode<T>(obj)); } } for(T obj:lists){ TreeNode<T> currentNode = treeMap.get(obj.getId()); TreeNode<T> 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<T> findById(Integer id){ TreeNode<T> treeNode = treeMap.get(id); return treeNode; } //遞歸獲取下屬實例 public void findNodeLeaves(TreeNode<T> node,List<T> 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<T> cld : node.getChildren()){ findNodeLeaves(cld,collects); } } }
TreeNode
public class TreeNode<T> { private T data; private TreeNode<T> parent; private Set<TreeNode<T>> children = new HashSet<TreeNode<T>>(); public TreeNode() { } public TreeNode(T data) { this.data = data; } public void addChild(TreeNode<T> child){ children.add(child); } public T getData() { return data; } public void setData(T data) { this.data = data; } public TreeNode<T> getParent() { return parent; } public void setParent(TreeNode<T> parent) { this.parent = parent; } public Set<TreeNode<T>> 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<Map<String,Object>> data = new ArrayList<Map<String,Object>>(); data = JsonTool.parseToObject(text,data.getClass()); List<OrgEmployeeInfo> infos = new ArrayList<OrgEmployeeInfo>(); for(Map map:data){ String idStr = (String) map.get("id"); Integer id = Integer.valueOf(idStr.substring(1)); String parIdStr = (String) map.get("parentId"); Integer parentId = Integer.valueOf(parIdStr.substring(1)); String name = (String)map.get("name"); OrgEmployeeInfo info = new OrgEmployeeInfo(id,name,parentId); Object orgCategory = map.get("orgCategory"); if(orgCategory == null){ info.setIsEmployee(true); } infos.add(info); } // List<OrgEmployeeInfo> infos = new ArrayList<OrgEmployeeInfo>(); // infos.add(new OrgEmployeeInfo(1,"boss",null)); // // infos.add(new OrgEmployeeInfo(2,"dep1",1)); // infos.add(new OrgEmployeeInfo(3,"dep2",1)); // infos.add(new OrgEmployeeInfo(4,"dep3",1)); // // infos.add(new OrgEmployeeInfo(5,"subdep1-1",2)); // infos.add(new OrgEmployeeInfo(6,"subdep1-2",2)); // infos.add(new OrgEmployeeInfo(7,"subdep1-3",2)); // // infos.add(new OrgEmployeeInfo(9665,"subdep3-1",4)); Tree<OrgEmployeeInfo> tree = new Tree<OrgEmployeeInfo>(infos); TreeNode<OrgEmployeeInfo> node = tree.findById(674); List<OrgEmployeeInfo> childs = new ArrayList<OrgEmployeeInfo>(); tree.findNodeLeaves(node,childs); for(OrgEmployeeInfo cld:childs){ System.out.println(cld.toString()); } System.out.println(ReflectTool.getObjectSize(infos, SizeEnum.M)); } }