设计模式 -- 组合模式

369 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第16天,点击查看活动详情

基本介绍

1)组合模式又叫部分整体模式,它创建了对象组的属性结构,将对象组合成树状结构以表示“整体-部分”的层次关系

2)组合模式依据树形结构来组合对象,用来表示部分以及整体层次

3)这种类型的设计模式属于结构型模式

4)组合模式使得用户对单个对象和嘴和对象的访问具有一致性,即:组合能让客户以一致的方式处理个别对象以及组合对象

组合模式的注意事项和细节

1)简化客户端操作。客户端只需要面对一致的对象而不用考虑整体部分或者节点叶子的问题

2)具有较强的扩展性。当我们要更改组合对象时,我们只需要调整内部的层次关系,客户端不用做出任何改变

3)方便创建出复杂的层次结构。客户端不用理会组合里面的组成细节,容易添加节点或者叶子从而创建出复杂的属性结构。

4)需要遍历组织结构,或者处理的对象具有树形结构时,非常适合使用组合模式

5)要求较高的抽象性,如果节点和叶子有很多差异性的话,比如很多方法和树形都不一样,不适合使用组合模式

类图

1.png

2.png

案例代码

package com.example.demo.design.componsite;

public abstract class MyElement {

    abstract void eat();

}

package com.example.demo.design.componsite;

public class Apple extends MyElement{
    @Override
    public void eat() {
        System.out.println("吃");
    }
}

package com.example.demo.design.componsite;

public class Banana extends MyElement{
    @Override
    public void eat() {
        System.out.println("吃🍌");
    }
}

package com.example.demo.design.componsite;

public class Pear extends MyElement{

    @Override
    public void eat() {
        System.out.println("吃🍐");
    }
}

package com.example.demo.design.componsite;

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

public class Plate {
    List<MyElement> list = new ArrayList<>();

    public void eat(){
        for(MyElement element : list){
            element.eat();
        }
    }

    public void add(MyElement element){
        list.add(element);
    }

    public void remove(MyElement element){
        list.remove(element);
    }
}

package com.example.demo.design.componsite;

public class Client {
    public static void main(String[] args) {
        Plate plate = new Plate();
        plate.add(new Apple());
        Banana banana = new Banana();
        plate.add(banana);
        plate.eat();
        System.out.println("------------");
        plate.remove(banana);
        plate.eat();
        System.out.println("------------");
        Plate plate1 = new Plate();
        plate1.add(new Pear());
        plate1.add(new Apple());
        plate1.add(new Banana());
        plate1.eat();
    }
}

结果

3.png

组合模式在jdk集合的源码分析

java的集合类-HashMap

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

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

    private static final long serialVersionUID = 362498820763181265L;

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

	/**
     * Copies all of the mappings from the specified map to this map.
     * These mappings will replace any mappings that this map had for
     * any of the keys currently in the specified map.
     *
     * @param m mappings to be stored in this map
     * @throws NullPointerException if the specified map is null
     */
    public void putAll(Map<? extends K, ? extends V> m) {
        putMapEntries(m, true);
    }
}