欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【09】结构型-组合Composite模式

程序员文章站 2022-06-13 12:58:39
...

一、上下文及问题

    将对象组合成树型结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。


二、常见场景

1、如果你想表示对象的部分-整体层次结构,可以选用组合模式,把整体和部分的操作统一起来,是的层次结构实现更简单,从外部来使用这个层次结构也容易。

2、如果你希望统一滴使用组合结构中的所有对象,可以选用组合模式,这正是组合模式提供的主要功能。


比如管理品类,人员组织结构。


三、解决方法

1、安全型的组合模式

     父类只定义公共的方法,客户端得区分哪些是部分哪些是整体,各自的操作方法有不同,之所以说是安全,是因为,没有把特殊子类不支持的方法放到公用类里头,不会引发操作不支持。


2、透明的组合模式

    父类在公共方法里头,定义了管理方法,对客户端来说是透明的,它不需要区分谁是整体谁是部分,但是可能引用操作不安全,比如调用的方法,特殊子类并不支持。


四、抽象模型

【09】结构型-组合Composite模式


五、代码实例 

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 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();
    }
}

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 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();
    }
}


3、组织结构实例

    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));
    }
}


转载于:https://my.oschina.net/scipio/blog/282754