java23中设计模式之组合模式

  • Post author:
  • Post category:java


上一节说到代理模式:

https://blog.csdn.net/zhanglei082319/article/details/88672268

代理模式:代理者拥有委托人的部分权限,代理者也可以在代理的同时加上自己的部分业务

今天说一种新的设计模式:组合模式


组合模式: 对象自身包含其他对象的引用,以达到组合对象数据的效果

树形的数据结构生活中非常常见,比如国家城市县镇地址,公司部门子部门班组,盘符目录子目录文件等等。这种一层嵌套者一层的数据的构建,在java中,组合设计模式就起到了用武之地。

这里就以国家城市县镇例子,简单将组合模式用代码来实现。


1、先定义一个地址节点接口

/**
 * 地址节点
 */
public interface Node {

    /**
     * 当前节点名称
     */
    String  name();

    /**
     * 父节点名称
     */
    String  parentName();

    /**
     * 子节点名称
     */
    List<Node> childNode();


    /**
     * 添加子节点
     */
    void   addChildNode(Node childNode);
}


2、定义一个地址实现

/**
 * 地址实现元素
 */
public class Element implements Node {

    private String name;

    /**
     * 父节点名称
     */
    private String parentName;

    private List<Node> childNode = new LinkedList<>();

    public Element(String name,String parentName){
        this.name = name;
        this.parentName = parentName;
    }

    @Override
    public void  addChildNode(Node child){
        this.childNode.add(child);
    }


    @Override
    public String name() {
        return this.name;
    }

    @Override
    public String parentName() {
        return this.parentName;
    }

    @Override
    public List<Node> childNode() {
        return this.childNode;
    }
}


3、定义叶子地址实现(就是没有子地址的地址)

/**
 * 叶子地址
 */
public class Leaf implements Node {
    private String name;

    private String parentName;

    public Leaf(String name,String parentName){
        this.name = name;
        this.parentName = parentName;
    }

    @Override
    public String name() {
        return this.name;
    }

    @Override
    public String parentName() {
        return this.parentName;
    }

    @Override
    public List<Node> childNode() {
        return null;
    }

    @Override
    public void addChildNode(Node childNode) {
        throw new UnsupportedOperationException("unspport");
    }
}


最后我们来测试一下:

  public static void main(String[] args) {
        //主元素
        Element shanghai = new Element("上海",null);
        //子元素
        Element pudong = new Element("浦东新区","上海");
        Element huangpu = new Element("黄埔区","上海");
        //孙元素
        Leaf lujiazui = new Leaf("陆家嘴","浦东新区");
        Leaf babaiban = new Leaf("八佰伴","浦东新区");
        Leaf waitan = new Leaf("外滩","黄埔区");


        //组合
        pudong.addChildNode(lujiazui);
        pudong.addChildNode(babaiban);

        huangpu.addChildNode(waitan);

        shanghai.addChildNode(pudong);
        shanghai.addChildNode(huangpu);

        System.out.println(shanghai);
  }

执行结果如下:

这样一个简单的地址树形数据就完成了。

扩展一下,如果地址数量过多,可以进行循环递归构建树形数据,如下

    private static Node build(List<Node> allNodes){
        Node element = null;
        Iterator<Node> iterator = allNodes.iterator();
        while(iterator.hasNext()){
            Node node = iterator.next();
            if(node.parentName() == null){
                element = node;
                iterator.remove();
                break;
            }
        }
        recursion(allNodes,element);
        return element;
    }


    private static void  recursion(List<Node> allNodes,Node result){
        Iterator<Node> iterator = allNodes.iterator();
        while(iterator.hasNext()) {
            Node node = iterator.next();
            if(node.parentName().equals(result.name())){
                result.addChildNode(node);
                recursion(allNodes,node);
            }
        }
    }

    public static void main(String[] args) {
        //主元素
        Element shanghai = new Element("上海",null);
        //子元素
        Element pudong = new Element("浦东新区","上海");
        Element huangpu = new Element("黄埔区","上海");
        //孙元素
        Leaf lujiazui = new Leaf("陆家嘴","浦东新区");
        Leaf babaiban = new Leaf("八佰伴","浦东新区");
        Leaf waitan = new Leaf("外滩","黄埔区");

        List<Node> nodes = new LinkedList<>();
        nodes.add(shanghai);
        nodes.add(pudong);
        nodes.add(huangpu);
        nodes.add(lujiazui);
        nodes.add(babaiban);
        nodes.add(waitan);

        Node element = build(nodes);
        System.out.println();
    }

执行结果如下,并没有变化。

以上



版权声明:本文为zhanglei082319原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。