设计模式--组合设计模式

组合设计模式

将对象组合成树形结构,以表示“部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性。

1. 使用场景

当用户需要忽略组合对象和单个对象的不同,统一使用组合结构中的所有对象时,可使用该模式。
当用户调用根节点的方法时,会调用树中所有节点的方法。

2. 角色

首先树状结构肯定含有根节点、分枝节点、叶子节点。

  • Component 抽象根节点,规定了节点拥有的方法。
  • Composite 定义枝干节点的行为,存储子节点。
  • Leaf 定义叶子节点,定义节点行为。

3. 实践

安全的组合模式:是指分枝和叶子节点使用不同的类型,客户端调用时,需要直接使用Component的实现类。缺点在于违背了依赖倒置原则,用户依赖节点具体实现。不是面向接口编程。

// 1.定义抽象根节点
public abstract class Component {
    protected String name;

    public Component(String name) {
        this.name = name;
    }
    // 具体的逻辑方法由子类实现
    public abstract void doSomething();

}

// 2.定义枝干节点,实现对子节点的操作,实现分枝节点规定的行为
public class Composite extends Component {
    // 存储节点的容器
    private List<Component> mComponents = new ArrayList<>();

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

    @Override
    public void doSomething() {
        System.out.println(name);
        // 叶子节点么有list,肯定为空
        if (null != mComponents) {
            for (Component c : mComponents) {
                c.doSomething();
            }
        }
    }

    public void addChild(Component child) {
        mComponents.add(child);
    }

    public void removeChild(Component child) {
        mComponents.remove(child);
    }

    public Component getChild(int index) {
        return mComponents.get(index);
    }
}

// 3.定义叶子节点,规定叶子节点的行为
public class Leaf extends Component {

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

    @Override
    public void doSomething() {
        System.out.println(name);
    }

}

        /**
         * 组合对象,调用方法,安全的组合模式,
         */
        Composite root = new Composite("Root");

        Composite branch1 = new Composite("Branch1");
        Composite branch2 = new Composite("Branch2");

        Leaf leaf1 = new Leaf("Leaf1");
        Leaf leaf2 = new Leaf("Leaf2");
        Leaf leaf3 = new Leaf("Leaf3");
        Leaf leaf4 = new Leaf("Leaf4");

        root.addChild(branch1);
        root.addChild(branch2);

        branch1.addChild(leaf1);
        branch1.addChild(leaf3);
        branch2.addChild(leaf2);
        branch2.addChild(leaf4);

        root.doSomething();

透明的组合模式 指组合结构中所有节点都有着相同的结构,在方法内部区分不同节点。符合依赖倒置原则。

// 1. 定义抽象根节点,包含了分枝节点和叶子节点的所有方法。
public abstract class Dir {
    protected List<Dir> mDirs=new ArrayList<>();
    private String name;

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

    // 使用透明的组合模式,把文件和文件夹中要用到的方法都声明了。
    public abstract void addDir(Dir dir);
    public abstract void rmDir(Dir dir);
    public abstract void clear();
    public abstract void print();
    public abstract List<Dir> getFiles();

    public String getName() {
        return name;
    }

}

// 2. 分枝节点的具体实现。
public class Folder extends Dir {

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

    @Override
    public void addDir(Dir dir) {
        mDirs.add(dir);
    }

    @Override
    public void rmDir(Dir dir) {
        mDirs.remove(dir);
    }

    @Override
    public void clear() {
        mDirs.clear();
    }

    @Override
    public void print() {
        System.out.print(getName() + "(");
        Iterator<Dir> iter = mDirs.iterator();
        while (iter.hasNext()){
            Dir dir=iter.next();
            dir.print();
            if (iter.hasNext()){
                System.out.print(", ");
            }
        }
        System.out.print(")");
    }

    @Override
    public List<Dir> getFiles() {
        return null;
    }
}

// 3. 叶子节点具体实现,屏蔽叶子节点不支持的方法。
public class File extends Dir {

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

    @Override
    public void addDir(Dir dir) {
        throw new UnsupportedOperationException("文件对象不支持该操作!");
    }

    @Override
    public void rmDir(Dir dir) {
        throw new UnsupportedOperationException("文件对象不支持该操作!");
    }

    @Override
    public void clear() {
        throw new UnsupportedOperationException("文件对象不支持该操作!");
    }

    @Override
    public void print() {
        System.out.print(getName());
    }

    @Override
    public List<Dir> getFiles() {
        throw new UnsupportedOperationException("文件对象不支持该操作!");
    }
}

        /**
         * 以下是透明的组合模式,叶子节点屏蔽了部分方法。
         */
        Dir diskC=new Folder("C");
        diskC.addDir(new File("imdb.txt"));

        Dir dirWin=new Folder("Windows");
        dirWin.addDir(new File("explorer.exe"));
        diskC.addDir(dirWin);

        Dir dirPer=new Folder("PerfLogs");
        dirPer.addDir(new File("null.txt"));
        diskC.addDir(dirPer);

        Dir dirPro=new Folder("ProgramFile");
        dirPro.addDir(new File("ftp.txt"));
        diskC.addDir(dirPro);

        diskC.print();

4. 总结

View 和 ViewGroup 就是使用的组合模式

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值