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

一、上下文及问题

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


二、常见场景

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

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


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


三、解决方法

1、安全型的组合模式

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


2、透明的组合模式

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


四、抽象模型

062527_S23L_1383356.png


五、代码实例 

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值