【09】結構型-組合Composite模式

1、上下文及問題

    將對象組合成樹型結構以表示「部分-總體」的層次結構。組合模式使得用戶對單個對象和組合對象的使用具備一致性。java


2、常見場景

一、若是你想表示對象的部分-總體層次結構,能夠選用組合模式,把總體和部分的操做統一塊兒來,是的層次結構實現更簡單,從外部來使用這個層次結構也容易。node

二、若是你但願統一滴使用組合結構中的全部對象,能夠選用組合模式,這正是組合模式提供的主要功能。json


好比管理品類,人員組織結構。安全


3、解決方法

一、安全型的組合模式

     父類只定義公共的方法,客戶端得區分哪些是部分哪些是總體,各自的操做方法有不一樣,之因此說是安全,是由於,沒有把特殊子類不支持的方法放到公用類裏頭,不會引起操做不支持。this


二、透明的組合模式

    父類在公共方法裏頭,定義了管理方法,對客戶端來講是透明的,它不須要區分誰是總體誰是部分,可是可能引用操做不安全,好比調用的方法,特殊子類並不支持。
url


4、抽象模型


5、代碼實例 

一、安全型

   抽象類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));
    }
}
相關文章
相關標籤/搜索