Java设计模式(五) 多态的极致应用——组合模式

  原创文章,同步发自作者个人博客,转载请在文章开头处以超链接注明出处http://www.jasongj.com/design_pattern/composite/

组合模式介绍

组合模式定义

组合模式(Composite Pattern)将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户可以使用一致的方法操作单个对象和组合对象。

组合模式类图

组合模式类图如下

组合模式角色划分

  • 抽象组件,如上图中的Component
  • 简单组件,如上图中的SimpleComponent
  • 复合组件,如上图中的CompositeComponent

组合模式实例

实例介绍

对于一家大型公司,每当公司高层有重要事项需要通知到总部每个部门以及分公司的各个部门时,并不希望逐一通知,而只希望通过总部各部门及分公司,再由分公司通知其所有部门。这样,对于总公司而言,不需要关心通知的是总部的部门还是分公司。

实例类图

组合模式实例类图如下(点击可查看大图)

实例解析

本例代码可从作者Github下载

抽象组件

抽象组件定义了组件的通知接口,并实现了增删子组件及获取所有子组件的方法。同时重写了hashCodeequales方法(至于原因,请读者自行思考。如有疑问,请在评论区留言)。

package com.jasongj.organization;

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

public abstract class Organization {

  private List childOrgs = new ArrayList();

  private String name;

  public Organization(String name) {
    this.name = name;
  }

  public String getName() {
    return name;
  }

  public void addOrg(Organization org) {
    childOrgs.add(org);
  }

  public void removeOrg(Organization org) {
    childOrgs.remove(org);
  }

  public List getAllOrgs() {
    return childOrgs;
  }

  public abstract void inform(String info);

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

  @Override
  public boolean equals(Object org){
    if(!(org instanceof Organization)) {
      return false;
    }
    return this.name.equals(((Organization) org).name);
  }

}

简单组件(部门)

简单组件在通知方法中只负责对接收到消息作出响应。

package com.jasongj.organization;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Department extends Organization{

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

  private static Logger LOGGER = LoggerFactory.getLogger(Department.class);

  public void inform(String info){
    LOGGER.info("{}-{}", info, getName());
  }

}

复合组件(公司)

复合组件在自身对消息作出响应后,还须通知其下所有子组件

package com.jasongj.organization;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Company extends Organization{

  private static Logger LOGGER = LoggerFactory.getLogger(Company.class);

  public Company(String name) {
    super(name);
  }

  public void inform(String info){
    LOGGER.info("{}-{}", info, getName());
    List allOrgs = getAllOrgs();
    allOrgs.forEach(org -> org.inform(info+"-"));
  }

}

组合模式优缺点

组合模式优点

  • 高层模块调用简单。组合模式中,用户不用关心到底是处理简单组件还是复合组件,可以按照统一的接口处理。不必判断组件类型,更不用为不同类型组件分开处理。
  • 组合模式可以很容易的增加新的组件。若要增加一个简单组件或复合组件,只须找到它的父节点即可,非常容易扩展,符合“开放-关闭”原则。

组合模式缺点

  • 无法限制组合组件中的子组件类型。在需要检测组件类型时,不能依靠编译期的类型约束来实现,必须在运行期间动态检测。

组合模式与OOP原则

已遵循的原则

  • 依赖倒置原则(复合类型不依赖于任何具体的组件而依赖于抽象组件)
  • 迪米特法则
  • 里氏替换原则
  • 接口隔离原则
  • 单一职责原则
  • 开闭原则

未遵循的原则

  • NA

Java设计模式系列

  • Java设计模式(一) 简单工厂模式不简单
  • Java设计模式(二) 工厂方法模式
  • Java设计模式(三) 抽象工厂模式
  • Java设计模式(四) 观察者模式
  • Java设计模式(五) 组合模式
  • Java设计模式(六) 代理模式 VS. 装饰模式
  • Java设计模式(七) Spring AOP JDK动态代理 vs. cglib
  • Java设计模式(八) 适配器模式
  • Java设计模式(九) 桥接模式
  • Java设计模式(十) 你真的用对单例模式了吗?
  • Java设计模式(十一) 享元模式
  • Java设计模式(十二) 策略模式
  • Java设计模式(十三) 别人再问你设计模式,叫他看这篇文章

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