深入理解23种设计模式(8) -- 组合模式

734 阅读3分钟

在这里插入图片描述

介绍

组合模式 (Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单位的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层次。这种类型的设计模式属于结构型模式,它创建来对象组的树形结构。

在这里插入图片描述

需求:

展示一个学校有多少个学校院系组成,一个学院有多少个学院,一个学院有多个系。

  • 清华大学
    • 计算机学院
      • 计算机科学与技术
      • 软件工程
    • 信息工程专业
      • 通信工程
      • 信息工程

  1. 创建 OrganizationComponent 类 该类带有 OrganizationComponent 对象
@Data
@ToString
public abstract class OrganizationComponent {

    /**
     * 说明
     */
    private String name;

    /**
     * 说明
     */
    private String des;


    /**
     * 添加方法
     * @param component
     */
    protected void add(OrganizationComponent component){
        throw new UnsupportedOperationException();
    }

    /**
     * 删除
     * @param component
     */
    protected void remove(OrganizationComponent component){
        throw new UnsupportedOperationException();
    }

    protected abstract void print();
    

    public OrganizationComponent(String name, String des) {
        this.name = name;
        this.des = des;
    }
}

  1. 创建University 学校类
public class University extends OrganizationComponent{

    List<OrganizationComponent> list = new ArrayList<>();


    public University(String name, String des) {
        super(name, des);
    }


    @Override
    protected void add(OrganizationComponent component) {
        list.add(component);
    }

    @Override
    protected void remove(OrganizationComponent component) {
        list.remove(component);
    }

    @Override
    protected void print() {
        System.out.println("----"+getName()+"---");
        list.stream().forEach( component -> {
             component.print();
        });
    }
}

  1. 创建学院类
public class College extends OrganizationComponent{
    List<OrganizationComponent> list = new ArrayList<>();


    public College(String name, String des) {
        super(name, des);

    }


    @Override
    protected void add(OrganizationComponent component) {
        list.add(component);
    }

    @Override
    protected void remove(OrganizationComponent component) {
        list.remove(component);
    }

    @Override
    protected void print() {
        System.out.println("--------"+getName()+"--------");
        list.stream().forEach( component -> {
            component.print();
        });
    }
}

  1. 创建专业类
public class Department extends OrganizationComponent{


    public Department(String name, String des) {
        super(name, des);

    }


    @Override
    protected void print() {
        System.out.println("------------"+getName()+"------------");
    }
}
  1. Client
public class Client {

    public static void main(String[] args) {
        //从大到小建立大学
        University university = new University("清华", "985");

        //创建学院
        College college = new College("计算机学院", "计算机学院");
        College college2 = new College("信息工程学院", "信息工程学院");

        //添加专业
        college.add(new Department("计算机科学与技术","计算机科学与技术"));
        college.add(new Department("网络工程","网络工程"));

        college2.add(new Department("通信工程","通信工程"));
        college2.add(new Department("信息工程","通信工程"));


        university.add(college);
        university.add(college2);
        university.print();
    }
}

在这里插入图片描述

组合模式在JDK Map中使用

  • Map 就是一个抽象的构件,类似于组合模式中的Component;
  • HashMap是中间的构件,只不过在HashMap与Component之间多了一层AbstractMap<K,V>,并且重写了Map中put(),putAll()等方法;
  • Node是HashMap中的静态内部类,类似于Leaf叶子节点

在这里插入图片描述

Map 接口 :顶级接口

public interface Map<K,V> {

   
	V put(K key, V value);
	void putAll(Map<? extends K, ? extends V> m);
    ………………
}

AbstractMap 抽象类实现来Map接口 :接口实现,扩展

public abstract class AbstractMap<K,V> implements Map<K,V> {


	public V put(K key, V value) {
	        throw new UnsupportedOperationException();
	    }

	public void putAll(Map<? extends K, ? extends V> m) {
	        for (Map.Entry<? extends K, ? extends V> e : m.entrySet())
	            put(e.getKey(), e.getValue());
	    }


}

HashMap :方法实现

public class HashMap<K,V> extends AbstractMap<K,V>
    implements Map<K,V>, Cloneable, Serializable {

    public V put(K key, V value) {
        return putVal(hash(key), key, value, false, true);
    }


	public void putAll(Map<? extends K, ? extends V> m) {
	        putMapEntries(m, true);
	    }
}

HashMap中的内部类 Node :他其实就是我们组合模式中所讲述的Leaf对象,它没有再组合任何的子节点,提供的也只有get方法和set方法

static class Node<K,V> implements Map.Entry<K,V> {
        final int hash;
        final K key;
        V value;
        Node<K,V> next;

        Node(int hash, K key, V value, Node<K,V> next) {
            this.hash = hash;
            this.key = key;
            this.value = value;
            this.next = next;
        }

        public final K getKey()        { return key; }
        public final V getValue()      { return value; }
        public final String toString() { return key + "=" + value; }

        public final int hashCode() {
            return Objects.hashCode(key) ^ Objects.hashCode(value);
        }

        public final V setValue(V newValue) {
            V oldValue = value;
            value = newValue;
            return oldValue;
        }

        public final boolean equals(Object o) {
            if (o == this)
                return true;
            if (o instanceof Map.Entry) {
                Map.Entry<?,?> e = (Map.Entry<?,?>)o;
                if (Objects.equals(key, e.getKey()) &&
                    Objects.equals(value, e.getValue()))
                    return true;
            }
            return false;
        }
    }
  • Map中的HashMap是应用了组合模式来实现的


github Demo地址 : ~~~传送门~~~

个人博客地址:blog.yanxiaolong.cn/