设计模式-组合模式

    我们知道Java里共有23种设计模式,使客户端对单个对象和组合对象保持一致的方式处理,组合模式属于结构型设计模式。

组合模式

定义

组合模式也称为整体-部分模式,它的宗旨是通过将单个对象(叶子节点)和组合对象(树枝节点)用相同的接口进行表示。

适用场景

(1) 希望客户端可以忽略组合对象与单个对象的差异。
(2) 对象层次具备整体和部分,呈树形结构(如树形结构、公司组织架构等)。

优点

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

缺点

(1) 限制类型时会更加负责。
(2) 使设计变得更加抽象。

透明组合模式实例

    所有公共方法都定义在 Component 中,这样做的好处是客户端无需分辨是叶子节点(Leaf)和树枝节点(Composite),它们具备完全一致的接口。

public abstract class Component {

    public void addChild(Component component) {
        throw new UnsupportedOperationException("不支持添加操作");
    }

    public void removeChild(Component component) {
        throw new UnsupportedOperationException("不支持删除操作");
    }

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

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

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

    private String name;

    private double price;

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

    @Override
    public String getName(Component component) {
        return this.name;
    }

    @Override
    public double getPrice(Component component) {
        return this.price;
    }

    @Override
    public void print() {
        System.out.println(name + " (¥" + price + "元)");
    }
}
public class CoursePackage extends Component {

    private String name;

    private Integer level;

    private List<Component> items = new ArrayList<Component>();

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

    @Override
    public void addChild(Component component) {
        items.add(component);
    }

    @Override
    public String getName(Component component) {
        return this.name;
    }

    @Override
    public void removeChild(Component component) {
        items.remove(component);
    }

    @Override
    public void print() {
        System.out.println(this.name);
        for (Component component : items) {
            //控制显示格式
            if (this.level != null) {
                for (int i = 0; i < this.level; i++) {
                    //打印空格控制格式
                    System.out.print(" ");
                }
                for (int i = 0; i < this.level; i++) {
                    //每一行开始打印一个+号
                    if (i == 0) {
                        System.out.print("+");
                    }
                    System.out.print("-");
                }
            }
            //打印标题 
            component.print();
        }
    }
}
public class Test {

    public static void main(String[] args) {
        System.out.println("============透明写法的组合模式===========");
        Component javaBase = new Course("Java 入门课程", 8280);
        Component ai = new Course("人工智能", 5000);

        Component packageCourse = new CoursePackage("Java 架构师课程", 2);
        Component design = new Course("Java 设计模式", 1500);
        Component source = new Course("并发编程", 2000);
        Component softSkill = new Course("源码分析", 3000);
        packageCourse.addChild(design);
        packageCourse.addChild(source);
        packageCourse.addChild(softSkill);

        Component catalog = new CoursePackage("课程主目录", 1);
        catalog.addChild(javaBase);
        catalog.addChild(ai);
        catalog.addChild(packageCourse);
        catalog.print();
    }
}

安全组合模式实例

    安全组合模式是只规定系统各个层次的最基础的一致行为,而把组合(树节点)本身的方法(管理子类对象的添加,删除等)放到自身当中。

public abstract class Directory {
    protected String name;

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

    public abstract void show();
}
public class File extends Directory {

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

    @Override
    public void show() {
        System.out.println(this.name);
    }
}
public class Folder extends Directory {
    private List<Directory> dirs;
    private Integer level;

    public Folder(String name, Integer level) {
        super(name);
        this.level = level;
        dirs = new ArrayList<Directory>();
    }

    public boolean add(Directory dir) {
        return this.dirs.add(dir);
    }

    public boolean remove(Directory dir) {
        return this.dirs.remove(dir);
    }

    public Directory get(int index) {
        return this.dirs.get(index);
    }

    @Override
    public void show() {
        System.out.println(this.name);
        for (Directory dir : this.dirs) {
            //控制显示格式
            if (this.level != null) {
                //打印空格控制格式
                for (int i = 0; i < this.level; i++) {
                    System.out.print(" ");
                }
                for (int i = 0; i < this.level; i++) {
                    //每一行开始打印一个+号
                    if (i == 0) {
                        System.out.print("+");
                    }
                    System.out.print("-");
                }
            }
            //打印名称
            dir.show();
        }
    }
}
public class Test {
    public static void main(String[] args) {
        System.out.println("============安全写法的组合模式===========");
        File qq = new File("QQ.exe");
        File wx = new File("微信.exe");
        Folder office = new Folder("办公软件", 2);
        File word = new File("Word.exe");
        File ppt = new File("PowerPoint.exe");
        File excel = new File("Excel.exe");
        office.add(word);
        office.add(ppt);
        office.add(excel);
        Folder wps = new Folder("金山软件", 3);
        wps.add(new File("WPS.exe"));
        office.add(wps);
        Folder root = new Folder("根目录", 1);
        root.add(qq);
        root.add(wx);
        root.add(office);
        root.show();
    }
}
以上为个人对组合模式的总结。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。