组合模式

定义:将对象组合成树形结构以表示 "部分 - 整体" 的层次结构。组合模式使客户端对单个对象和组合对象保持一致的方式处理。

类型:结构型

打个比方,我们有一个树形结构的菜单,然后菜单里面还有子菜单,那么在子菜单里面还有可能有子菜单的子菜单,而且对这些菜单的操作大体上是相同的,那么在这种树形结构的情况下,可以使用组合模式。

组合模式_第1张图片

 使用场景:

  1. 希望客户端可以忽略组合对象与单个对象的差异时
  2. 处理一个树形结构时

个人理解:

  • 一头牛也是赶,一群牛羊也是放。就是放一只牛和放一群牛和羊的方法都是一样的,看着他们好好吃草别丢了就行了。

优点:

  1. 清楚的定义分层次的复杂对象,表示对象的全部或部分层次
  2. 让客户端忽略了层次的差异,方便对整个层次结构进行控制
  3. 简化客户端的代码
  4. 符合开闭原则

缺点:

  1. 限制类型时较为复杂
  2. 使设计变得更加抽象

相关设计模式:

  • 组合模式和访问者模式

Coding:

场景:慕课网里面有很多课程,也有课程目录,课程有名称和价格。Java 课程分属于 Java 课程目录下,Java课程目录下有很多java课程,Python 目录下有很多 python 课程,使课程目录和课程继承同一个抽象类,例如目录组件,那么就可以把课程本身还有由课程组合成的课程目录视为同一类对象进行操作,但是在操作上还是会有一些差别,具体的差别再定制化处理,例如说打印这个操作我们可以打印课程的名称和价格,我们也可以打印课程目录,把课程目录下边所有的课程打印出来,对于这个操作可认为是一类操作。他们俩是相通的。

/**
 * CatalogComponent : 目录组件,抽象接口,为组合中对象的父类。
 */
public abstract class CatalogComponent {
    public void add(CatalogComponent catalogComponent){
        throw new UnsupportedOperationException("不支持添加操作");
    }

    public void remove(CatalogComponent catalogComponent){
        throw new UnsupportedOperationException("不支持删除操作");
    }

    public String getName(CatalogComponent catalogComponent){
        throw new UnsupportedOperationException("不支持获取名称操作操作");
    }

    public double getPrice(CatalogComponent catalogComponent){
        throw new UnsupportedOperationException("不支持获取价格操作");
    }

    public void print(){
        throw new UnsupportedOperationException("不支持打印操作");
    }
}

/**
 * Course : 课程类,是目录组件的子类
 */
public class Course extends  CatalogComponent {
    private String name;
    private double price;

    public Course(String name, double price) {
        this.name = name;
        this.price = price;
    }

    @Override
    public String getName(CatalogComponent catalogComponent) {
        return this.name;
    }

    @Override
    public double getPrice(CatalogComponent catalogComponent) {
        return this.price;
    }

    @Override
    public void print() {
        System.out.println("Course name:" + name + " Price:" + price);
    }
}

/**
 * CourseCatalog : 课程目录类,目录组件的子类
 */
public class CourseCatalog extends CatalogComponent {
    private List items = new ArrayList();
    private String name;
    private Integer level;

    public CourseCatalog(String name, Integer level) {
        this.name = name;
        this.level = level;
    }

    @Override
    public void add(CatalogComponent catalogComponent) {
        items.add(catalogComponent);
    }

    @Override
    public void remove(CatalogComponent catalogComponent) {
        items.remove(catalogComponent);
    }

    /**
     * 定制化处理
     */
    @Override
    public void print() {
        System.out.println(this.name);
        for (CatalogComponent catalogComponent : items){
            if (this.level != null) {
                for (int i = 0; i < this.level; i++) {
                    System.out.print("  ");
                }
            }
            catalogComponent.print();
        }
    }
}

/**
 * Java Client
 */
public class Test {
    public static void main(String[] args) {
        CatalogComponent linuxCourse = new Course("Linux 课程", 11);
        CatalogComponent windowsCourse = new Course("Windows 课程", 11);

        CatalogComponent javaCourseCatalog = new CourseCatalog("Java 课程", 2);

        CatalogComponent mmallCourse1 = new Course("Java 电商一期", 55);
        CatalogComponent mmallCourse2 = new Course("Java 电商二期", 66);
        CatalogComponent designPattern = new Course("Java 设计模式", 77);

        javaCourseCatalog.add(mmallCourse1);
        javaCourseCatalog.add(mmallCourse2);
        javaCourseCatalog.add(designPattern);

        CatalogComponent imoocMainCourseCatalog = new CourseCatalog("慕课网课程主目录", 1);
        imoocMainCourseCatalog.add(linuxCourse);
        imoocMainCourseCatalog.add(windowsCourse);
        imoocMainCourseCatalog.add(javaCourseCatalog);

        imoocMainCourseCatalog.print();

        /**
         * 运行结果:树状结构
         * 慕课网课程主目录
         *   Course name:Linux 课程 Price:11.0
         *   Course name:Windows 课程 Price:11.0
         *   Java 课程
         *     Course name:Java 电商一期 Price:55.0
         *     Course name:Java 电商二期 Price:66.0
         *     Course name:Java 设计模式 Price:77.0
         */
    }
}

组合模式_第2张图片

源码:

你可能感兴趣的:(组合模式)