设计模式学习小结

设计模式小结-组合模式

2017-10-14  本文已影响82人  r09er

组合模式概述

有一款杀毒软件,该软件既可以对某个文件夹(Folder)杀毒,也可以对某个指定的文件(File)进行杀毒。该杀毒软件还可以根据各类文件的特点,为不同类型的文件提供不同的杀毒方式,例如图像文件(ImageFile)和文本文件(TextFile)的杀毒方式就有所差异。文件夹的模型其实就是一种树的结构,对于杀毒功能,无论是文件夹还是文件,用户最终并不关心他是如何实现,只关心杀毒的类型,所以希望调用杀毒功能后会有一个统一的处理,这个时候就需要用上组合模式,它可以让叶子对象(File)和容器对象(Folder)的使用具有一致性。

使用示例

有一个界面控件库,界面控件分为两大类,一类是单元控件,例如按钮、文本框等,一类是容器控件,例如窗体、中间面板等,试用组合模式设计该界面控件库。

UML图

示例解析

抽象控件Component,对所有控件都有一个操作方法,同时也添加了容器控件的“增删查”方法,对于实现类,只需针对operation方法作具体操作,其中容器的operation操作中,会将持有的单元控件进行遍历操作其中的operation方法。

由于Component抽象了容器类控件的add(),remove(),getChild()方法,但是对于单元控件这部分功能并不需要.所以要在实现父类方法的时候正确提示用户,也可以考虑将这部分功能去掉,只在容器类中添加,在很多时候为了安全性,会选择将非共有的方法放在子类实现(称为安全组合模式),无论采取哪种解决方案,对抽象能力有一定要求,这也是组合模式的一个弊端。

示例代码

抽象Component

public abstract class Component {
    public abstract void add(Component component);
    public abstract void remove(Component component);
    public abstract Component getChild(int index);
    //共有的操作方法
    public abstract void operation();
}

具体实现类

public class ButtonComponent extends Component{
    @Override
    public void add(Component component) {
        System.out.println("不支持该方法");
    }

    @Override
    public void remove(Component component) {
        System.out.println("不支持该方法");
    }

    @Override
    public Component getChild(int index) {
        System.out.println("不支持该方法");
        return null;
    }

    @Override
    public void operation() {
        System.out.println("按钮点击");
    }
}

//单元控件
public class TextAreaComponent extends Component{

    @Override
    public void add(Component component) {
        System.out.println("不支持该方法");
    }

    @Override
    public void remove(Component component) {
        System.out.println("不支持该方法");
    }

    @Override
    public Component getChild(int index) {
        System.out.println("不支持该方法");
        return null;
    }

    @Override
    public void operation() {
        System.out.println("操作输入框");
    }
}

//容器控件
public class PanelComponent extends Component {

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

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

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

    @Override
    public Component getChild(int index) {
        return componentList.get(index);
    }

    @Override
    public void operation() {
        for (Component component : componentList) {
            component.operation();
        }
    }
}

//容器控件
public class WindowComponent extends Component{

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


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

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

    @Override
    public Component getChild(int index) {
        return componentList.get(index);
    }

    @Override
    public void operation() {
        for (Component component : componentList) {
            component.operation();
        }
    }
}

调用

 Component buttonComponent = new ButtonComponent();
Component textAreaComponent = new TextAreaComponent();
Component windowComponent = new WindowComponent(); windowComponent.add(buttonComponent);
windowComponent.add(textAreaComponent);
windowComponent.operation();

输出结果

按钮点击
操作输入框

组合模式优缺点

优点

缺点

适用场景

上一篇下一篇

猜你喜欢

热点阅读