您当前的位置: 首页 > 

Dongguo丶

暂无认证

  • 2浏览

    0关注

    472博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

设计模式之组合模式

Dongguo丶 发布时间:2019-01-13 18:47:11 ,浏览量:2

定义

​ 组合模式又叫部分整体模式,组合多个对象形成树形结构以表示“整体-部分”的结构层次。

​ 组合模式对单个对象(叶子对象)和组合对象(组合对象)具有一致性,它将对象组织到树结构中,可以用来描述整体与部分的关系。同时它也模糊了简单元素(叶子对象)和复杂元素(容器对象)的概念,使得客户能够像处理简单元素一样来处理复杂元素,从而使客户程序能够与复杂元素的内部结构解耦。

​ 在使用组合模式中需要注意一点也是组合模式最关键的地方:叶子对象和组合对象实现相同的接口。这就是组合模式能够将叶子节点和对象节点进行一致处理的原因。

 模式结构

 

​ 组合模式主要包含如下几个角色:

​ 1.Component :组合中的对象声明接口,在适当的情况下,实现所有类共有接口的默认行为。声明一个接口用于访问和管理Component子部件。

2.Leaf:叶子对象。叶子结点没有子结点。

3.Composite:容器对象,定义有枝节点行为,用来存储子部件,在Component接口中实现与子部件有关操作,如增加(add)和删除(remove)等。

​ 从模式结构中我们看出了叶子节点和容器对象都实现Component接口,这也是能够将叶子对象和容器对象一致对待的关键所在。

编写程序展示一个学校院系结构:需求是这样,要在一个页面中展示出学校的院系组成,一个学校有多个学院,一个学院有多个系。

 

思路分析和图解(类图)

 

创建一个抽象类OrganizationComponent

 大学College 学院University 系Department继承OrganizationComponent

Department是叶子节点,University 、Department是非叶子节点

代码实现:

package com.dongguo.composite;

/**
 * @author Dongguo
 * @date 2021/8/22 0022-14:58
 * @description:
 */
public abstract class OrganizationComponent {
    private String name; // 名字
    private String des; // 说明

    protected void add(OrganizationComponent organizationComponent) {
        //默认实现
        throw new UnsupportedOperationException();
    }

    protected void remove(OrganizationComponent organizationComponent) {
        //默认实现
        throw new UnsupportedOperationException();
    }

    //构造器
    public OrganizationComponent(String name, String des) {
        super();
        this.name = name;
        this.des = des;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDes() {
        return des;
    }

    public void setDes(String des) {
        this.des = des;
    }

    //方法print, 做成抽象的, 子类都需要实现
    protected abstract void print();
}
package com.dongguo.composite;

/**
 * @author Dongguo
 * @date 2021/8/22 0022-15:00
 * @description: 系
 */
public class Department extends OrganizationComponent {
    //没有集合
    public Department(String name, String des) {
        super(name, des);
    }

    //add , remove 就不用写了,因为他是叶子节点
    @Override
    public String getName() {

        return super.getName();
    }

    @Override
    public String getDes() {
        return super.getDes();
    }

    @Override
    protected void print() {
        System.out.println(getName());
    }
}
package com.dongguo.composite;

import java.util.ArrayList;
import java.util.List;

/**
 * @author Dongguo
 * @date 2021/8/22 0022-15:03
 * @description: 学院
 */
public class University extends OrganizationComponent {
    List organizationComponents = new ArrayList();

    // 构造器
    public University(String name, String des) {
        super(name, des);
    }

    // 重写add
    @Override
    protected void add(OrganizationComponent organizationComponent) {
        organizationComponents.add(organizationComponent);
    }

    // 重写remove
    @Override
    protected void remove(OrganizationComponent organizationComponent) {
        organizationComponents.remove(organizationComponent);
    }

    @Override
    public String getName() {
        return super.getName();
    }

    @Override
    public String getDes() {
        return super.getDes();
    }

    // print 方法,就是输出University 包含的学院
    @Override
    protected void print() {
        System.out.println("--------------" + getName() + "--------------");
        //遍历organizationComponents
        for (OrganizationComponent organizationComponent : organizationComponents) {
            organizationComponent.print();
        }
    }
}

package com.dongguo.composite;

import java.util.ArrayList;
import java.util.List;

/**
 * @author Dongguo
 * @date 2021/8/22 0022-14:58
 * @description: 大学
 */
public class College extends OrganizationComponent {
    //List 中存放的Department
    List organizationComponents = new ArrayList();
    // 构造器
    public College(String name, String des) {
        super(name, des);
    }
    // 重写add
    @Override
    protected void add(OrganizationComponent organizationComponent) {

// 将来实际业务中,Colleage 的add 和University add 不一定完全一样
        organizationComponents.add(organizationComponent);
    }
    // 重写remove
    @Override
    protected void remove(OrganizationComponent organizationComponent) {
        organizationComponents.remove(organizationComponent);
    }
    @Override
    public String getName() {
        return super.getName();
    }
    @Override
    public String getDes() {
        return super.getDes();
    }
    // print 方法,就是输出University 包含的学院
    @Override
    protected void print() {

        System.out.println("--------------" + getName() + "--------------");
        //遍历organizationComponents
        for (OrganizationComponent organizationComponent : organizationComponents) {
            organizationComponent.print();
        }
    }
}
package com.dongguo.composite;

/**
 * @author Dongguo
 * @date 2021/8/22 0022-15:02
 * @description:
 */
public class Client {
    public static void main(String[] args) {
        //从大到小创建对象学校
        OrganizationComponent university = new University("清华大学", " 中国顶级大学");
        //创建学院
        OrganizationComponent computerCollege = new College("计算机学院", " 计算机学院");
        OrganizationComponent infoEngineercollege = new College("信息工程学院", " 信息工程学院");
        //创建各个学院下面的系(专业)
        computerCollege.add(new Department("软件工程", " 软件工程不错"));
        computerCollege.add(new Department("网络工程", " 网络工程不错"));
        computerCollege.add(new Department("计算机科学与技术", " 计算机科学与技术是老牌的专业"));
        infoEngineercollege.add(new Department("通信工程", " 通信工程不好学"));
        infoEngineercollege.add(new Department("信息工程", " 信息工程好学"));
        //将学院加入到学校
        university.add(computerCollege);
        university.add(infoEngineercollege);

        university.print();
       // infoEngineercollege.print();
    }
}
运行结果:
--------------清华大学--------------
--------------计算机学院--------------
软件工程
网络工程
计算机科学与技术
--------------信息工程学院--------------
通信工程
信息工程

优点

​ 1、可以清楚地定义分层次的复杂对象,表示对象的全部或部分层次,使得增加新构件也更容易。

​ 2、客户端调用简单,客户端可以一致的使用组合结构或其中单个对象。

​ 3、定义了包含叶子对象和容器对象的类层次结构,叶子对象可以被组合成更复杂的容器对象,而这个容器对象又可以被组合,这样不断递归下去,可以形成复杂的树形结构。

​ 4、更容易在组合体内加入对象构件,客户端不必因为加入了新的对象构件而更改原有代码。

缺点

​ 1、使设计变得更加抽象,对象的业务规则如果很复杂,则实现组合模式具有很大挑战性,而且不是所有的方法都与叶子对象子类都有关联

 模式适用场景

​ 1、需要表示一个对象整体或部分层次,在具有整体和部分的层次结构中,希望通过一种方式忽略整体与部分的差异,可以一致地对待它们。

​ 2、让客户能够忽略不同对象层次的变化,客户端可以针对抽象构件编程,无须关心对象层次结构的细节。

模式总结

​ 1、 组合模式用于将多个对象组合成树形结构以表示“整体-部分”的结构层次。组合模式对单个对象(叶子对象)和组合对象(容器对象)的使用具有一致性。

​ 2、 组合对象的关键在于它定义了一个抽象构建类,它既可表示叶子对象,也可表示容器对象,客户仅仅需要针对这个抽象构建进行编程,无须知道他是叶子对象还是容器对象,都是一致对待。

​ 3、 组合模式虽然能够非常好地处理层次结构,也使得客户端程序变得简单,但是它也使得设计变得更加抽象,而且也很难对容器中的构件类型进行限制,这会导致在增加新的构件时会产生一些问题。

组合模式在JDK 集合的源码分析
package com.dongguo.composite;

import java.util.HashMap;
import java.util.Map;

/**
 * @author Dongguo
 * @date 2021/8/22 0022-15:27
 * @description:
 */
public class CompositeDemo {
    public static void main(String[] args) {
        Map hashMap = new HashMap();
        hashMap.put(0,"张三");
        Map map = new HashMap();
        map.put(1,"李四");
        map.put(2,"王五");
        hashMap.putAll(map);
        System.out.println(hashMap);
    }
}

1、HashMap HashMap中有一个putAll方法,参数是一个Map,这就是一种组合模式的体现:

 

   public void putAll(Map            
关注
打赏
1638062488
查看更多评论
0.0367s