设计模式课程 设计模式精讲 14-2 组合模式coding

1    代码演练

1.1    代码演练1(组合模式1)

1.2    代码演练2(组合模式1之完善)

1    代码演练
1.1    代码演练1(组合模式1)

需求:

打印出木木网的课程结构,

我们用一个组建类作为接口,课程类和目录类继承。

uml:

组件类:

package com.geely.design.pattern.structural.composite;

import java.io.IOException;

/**
 * 课程目录组件,可以被课程和课程目录继承
 */
public abstract class CatalogComponent {
    //添加目录
    public void addCatalog(CatalogComponent catalogComponent){
        throw new UnsupportedOperationException("不支持添加操作");
    }

    //移除目录
    public void removeCatalog(CatalogComponent catalogComponent){
        throw new UnsupportedOperationException("不支持移除操作");
    }

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

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

    //打印目录  注意这里抛出异常 是为了抽象类 的方法不被调取,之所以没有写抽象方法,是因为目录类和课程类总有些方法没有实现
    public void printCatalog(){
         throw new UnsupportedOperationException("不支持的操作");
    }
}

课程类:

package com.geely.design.pattern.structural.composite;

public class Course extends CatalogComponent {
    private String sCourseName;
    private double sCoursePrice;

    public Course(String sCourseName, double sCoursePrice) {
        this.sCourseName = sCourseName;
        this.sCoursePrice = sCoursePrice;
    }

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

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

    @Override
    public void printCatalog() {
        System.out.println("课程名称为"+sCourseName+",  课程价格为"+sCoursePrice);
    }
}

目录类:

package com.geely.design.pattern.structural.composite;

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

public class CourseCatalog extends CatalogComponent {
    private List<CatalogComponent> items = new ArrayList<CatalogComponent>();
    private String name;

    /**
     * 一定要写有参构造方法,因为后边还要打印日志
     * @param name
     */
    public CourseCatalog(String name) {
        this.name = name;
    }

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

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

    /**
     * 对于目录来说,课程名字可以出重写,
     * 所以这里可以进行修改!!!
     * @param catalogComponent
     * @return
     */
    @Override
    public String getName(CatalogComponent catalogComponent) {
       return this.name;
    }

    @Override
    public void printCatalog() {
        for(CatalogComponent catalogComponent :items){
            catalogComponent.printCatalog();
        }
    }
}

测试类:

package com.geely.design.pattern.structural.composite;

public class Test {

    public static void main(String [] args){
        CatalogComponent totalCourse = new CourseCatalog("课程总目录");
        CatalogComponent linuxCourse = new Course("linux课程",11);
        CatalogComponent windowsCourse = new Course("windows操作系统课程",22);
        CatalogComponent javaCatalog = new CourseCatalog("java课程目录");
        CatalogComponent javaHibernate = new Course("hibernate课程",33);
        CatalogComponent javaStruct2 = new Course("Struct2课程",44);
        CatalogComponent javaSpring = new Course("Spring课程",55);
javaCatalog.addCatalog(javaHibernate); javaCatalog.addCatalog(javaStruct2);
javaCatalog.addCatalog(javaSpring); totalCourse.addCatalog(linuxCourse); totalCourse.addCatalog(windowsCourse);
totalCourse.addCatalog(javaCatalog); totalCourse.printCatalog(); } }

打印日志:

课程名称为linux课程,  课程价格为11.0
课程名称为windows操作系统课程,  课程价格为22.0
课程名称为hibernate课程,  课程价格为33.0
课程名称为Struct2课程,  课程价格为44.0
课程名称为Spring课程,  课程价格为55.0

Process finished with exit code 0
1.2    代码演练2(组合模式1之完善)

1.1的缺陷是

没有打出目录结构

只修改了课程目录类 和测试类:

package com.geely.design.pattern.structural.composite;

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

public class CourseCatalog extends CatalogComponent {
    private List<CatalogComponent> items = new ArrayList<CatalogComponent>();
    private String name;
    private Integer level;//加入等级, 判断是否是目录,之所以不用int 是因为不用给它初始值, 也好做空判断

    /**
     * 一定要写有参构造方法,因为后边还要打印日志
     * @param name
     */
    public CourseCatalog(String name,Integer level) {
        this.name = name;
        this.level = level;
    }

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

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

    /**
     * 对于目录来说,课程名字可以出重写,
     * 所以这里可以进行修改!!!
     * @param catalogComponent
     * @return
     */
    @Override
    public String getName(CatalogComponent catalogComponent) {
       return this.name;
    }

    @Override
    public void printCatalog() {
        System.out.println(this.name);//打印目录名字
        for(CatalogComponent catalogComponent :items){
            if(this.level != null){
                for(int i = 0;i < level;i++){
                    System.out.print("  ");
                }
            }
            catalogComponent.printCatalog();//调用课程或者目录打印方法
        }
    }
}

测试类:

package com.geely.design.pattern.structural.composite;

public class Test {

    public static void main(String [] args){
        CatalogComponent totalCourse = new CourseCatalog("课程总目录",1);
        CatalogComponent linuxCourse = new Course("linux课程",11);
        CatalogComponent windowsCourse = new Course("windows操作系统课程",22);
        CatalogComponent javaCatalog = new CourseCatalog("java课程目录",2);
        CatalogComponent javaHibernate = new Course("hibernate课程",33);
        CatalogComponent javaStruct2 = new Course("Struct2课程",44);
        CatalogComponent javaSpring = new Course("Spring课程",55);
        javaCatalog.addCatalog(javaHibernate);
        javaCatalog.addCatalog(javaStruct2);
        javaCatalog.addCatalog(javaSpring);
        totalCourse.addCatalog(linuxCourse);
        totalCourse.addCatalog(windowsCourse);
        totalCourse.addCatalog(javaCatalog);
        totalCourse.printCatalog();
    }
}

打印日志:

课程总目录
  课程名称为linux课程,  课程价格为11.0
  课程名称为windows操作系统课程,  课程价格为22.0
  java课程目录
    课程名称为hibernate课程,  课程价格为33.0
    课程名称为Struct2课程,  课程价格为44.0
    课程名称为Spring课程,  课程价格为55.0

Process finished with exit code 0

课程类:

package com.geely.design.pattern.structural.composite;

public class Course extends CatalogComponent {
    private String sCourseName;
    private double sCoursePrice;

    public Course(String sCourseName, double sCoursePrice) {
        this.sCourseName = sCourseName;
        this.sCoursePrice = sCoursePrice;
    }

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

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

    @Override
    public void printCatalog() {
        System.out.println("课程名称为"+sCourseName+",  课程价格为"+sCoursePrice);
    }
}

组件类:

package com.geely.design.pattern.structural.composite;

import java.io.IOException;

/**
 * 课程目录组件,可以被课程和课程目录继承
 */
public abstract class CatalogComponent {
    //添加目录
    public void addCatalog(CatalogComponent catalogComponent){
        throw new UnsupportedOperationException("不支持添加操作");
    }

    //移除目录
    public void removeCatalog(CatalogComponent catalogComponent){
        throw new UnsupportedOperationException("不支持移除操作");
    }

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

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

    //打印目录  注意这里抛出异常 是为了抽象类 的方法不被调取,之所以没有写抽象方法,是因为目录类和课程类总有些方法没有实现
    public void printCatalog(){
         throw new UnsupportedOperationException("不支持的操作");
    }
}
原文地址:https://www.cnblogs.com/1446358788-qq/p/11521763.html