设计模式之组合模式

什么是组合模式

    组合模式是指组合多个对象形成树形结构以表示具有"整体-部分"关系的层次结构。组合模式对单个对象和组合对象的使用具有一致性。
    组合模式包括以下几个角色:
        Component(抽象构件):可以是接口或者抽象类,为叶子构件对象或容器构件对象声明接口,该角色中可以包含所有子类共有行为的声明和实现。
        Leaf(叶子构件):实现了抽象构件中声明的方法,该对象没有下级对象。
        Composite(容器构件):该角色包含下级对象。下级对象即可以是叶子构件也可以是容器构件,提供了一个集合用于存储子节点,实现了在抽象构件中定义的方法。
    组合模式的关键是定义一个抽象构件类,他即表示叶子构件也表示容器构件。客户端对抽象构件进行编程,可以对叶子和容器构件进行统一处理。
    在使用组合模式时,可以根据抽象构件类的定义形式将组合模式分为透明组合模式和安全组合模式:
        透明组合模式:在抽象构件类中声明所有管理成员对象的方法,确保所有的子类都有相同的方法。透明组合模式的缺点是不够安全,因为叶子对象和容器对象本质上是不一样的,叶子对象不会有下级对象,所以实现抽象构件中的方法毫无意义。
        安全组合模式:在抽象构件类中不会声明任何管理成员对象的方法,而是在组合构件中声明并实现,这样叶子对象就不需要管理这些方法。安全组合模式的缺点是不够透明,因此叶子构件和组合构件具有不同的方法,而容器构件中用于管理成员对象的方法没有在抽象构件中声明。
    组合模式是使用面向对象的思想来实现树形结构的构建与处理,描述了如何将容器对象和叶子对象进行递归组合,实现简单,灵活性好。

组合模式的优缺点

优点

  1. 组合模式可以清楚的定义分层次的复杂对象,表示对象的全部或部分层次,客户端可以忽略层次的差异,方便的对整个层次结构进行控制。
  2. 客户端对组合结构或单个对象可以统一处理。
  3. 在组合模式中新增容器构件或叶子构件无需修改代码,符合开闭原则。
  4. 组合模式为树形结构的面向对象实现提供了一种灵活的解决方案,通过叶子对象和容器对象饿递归组合,可以形成复杂的树形结构,但对树形结构的控制非常简单。

缺点

  1. 在增加新的构件时很难对容器中的构件类型进行限制,使用组合模式时,不能依赖类型来增加约束,因为他们都有相同的抽象层,在这种情况下,必须通过在运行时进行类型检查实现,这个过程实现较为复杂。

组合模式的应用场景

  1. 在具有"整体-部分"的层次结构中,希望通过一种方式忽略"整体-部分"的差异。
  2. 需要处理一个树形结构。
  3. 能够分离出叶子对象和容器对象,而且类型不固定,需要增加一些新的类型。

组合模式的案例

// 抽象构件
@Data
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;
    }

    protected abstract void print();

}

// 容器构件
public class University extends OrganizationComponent {

    List organizationComponents = new ArrayList();

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

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

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

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

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

    @Override
    protected void print() {
        System.out.println("--------------" + getName() + "--------------");
        //遍历 organizationComponents
        for (OrganizationComponent organizationComponent : organizationComponents) {
            organizationComponent.print();
        }
    }

}
public class College extends OrganizationComponent {

    List organizationComponents = new ArrayList<>();

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

    @Override
    protected void add(OrganizationComponent organizationComponent) {
        // 将来实际业务中,Colleage 的 add 和  University add 不一定完全一样
        organizationComponents.add(organizationComponent);
    }

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

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

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

    @Override
    protected void print() {
        System.out.println("--------------" + getName() + "--------------");
        //遍历 organizationComponents
        for (OrganizationComponent organizationComponent : organizationComponents) {
            organizationComponent.print();
        }
    }

}

// 叶子构件
public class Department extends OrganizationComponent {

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

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

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

	@Override
	protected void print() {
		System.out.println(getName());
	}

}

设计模式之组合模式_第1张图片

组合模式在源码中的应用

HashMap

// 抽象构件
public abstract class AbstractMap implements Map {
    public V put(K key, V value) {
        throw new UnsupportedOperationException();
    }
    
    public abstract Set> entrySet();
    ......
}


public class HashMap extends AbstractMap
    implements Map, Cloneable, Serializable {
    public V put(K key, V value) {
        return putVal(hash(key), key, value, false, true);
    }
    
    final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
                   boolean evict) {
        Node[] tab; Node p; int n, i;
        if ((tab = table) == null || (n = tab.length) == 0)
            n = (tab = resize()).length;
        if ((p = tab[i = (n - 1) & hash]) == null)
        ......
    }
    public Set> entrySet() {
        Set> es;
        return (es = entrySet) == null ? (entrySet = new EntrySet()) : es;
    }
    ......       
}


你可能感兴趣的:(设计模式,组合模式,设计模式,java,后端)