设计模式之组合模式


设计模式是经验总结,是学习软件设计的有效方法,因此,了解和理解现有的设计模式,是提高软件设计的有效途径之一,这里将介绍相关的设计模式,并通过示例了理解其用法。

组合模式(Composite Pattern)

组合模式将对象组合成树状结构来表现“整体/部分”的层级结构,让客户以一致的方式来处理个别对象以及对象组合。
定义
组合模式属于结构型模式,它创建了对象组的树形结构。
意图: 将对象组合成树形结构以表示"部分-整体"的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
主要解决: 它在我们树型结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以像处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元素的内部结构解耦。
何时使用: 1、您想表示对象的部分-整体层次结构(树形结构)。 2、您希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。
如何解决: 树枝和叶子实现统一接口,树枝内部组合该接口。
关键代码: 树枝内部组合该接口,并且含有内部属性 List,里面放 Component。
应用实例: 1、算术表达式包括操作数、操作符和另一个操作数,其中,另一个操作符也可以是操作数、操作符和另一个操作数。 2、在 JAVA AWT 和 SWING 中,对于 Button 和 Checkbox 是树叶,Container 是树枝。
优点: 1、高层模块调用简单。 2、节点自由增加。
缺点: 在使用组合模式时,其叶子和树枝的声明都是实现类,而不是接口,违反了依赖倒置原则。
使用场景: 部分、整体场景,如树形菜单,文件、文件夹的管理。
注意事项: 定义时为具体类。

示例

这里以Node类为基类,有Composite子类和Leaf子类,来说明组合模式的基本结构。
Node类是一个抽象基类,代码如下:

package cn.lut.curiezhang.designpattern.composite;

import java.util.ArrayList;

public abstract class Node {
    private String name = "";
    static int level = 0;
    ArrayList<Node> subElements = new ArrayList<>();

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

    public abstract void operation();

    public void add(Node node) {
        System.out.println("未实现子方法!");
    }

    public void remove(Node node) {
        System.out.println("未实现子方法!");
    }

    public void getChild() {
        System.out.println("未实现子方法!");
    }

    public String getName() {
        return name;
    }
}

Composite是Node类的子类,能够组合Node对象,代码如下:

package cn.lut.curiezhang.designpattern.composite;

import java.util.Iterator;

public class Composite extends Node {
    public Composite(String name) {
        super(name);
    }

    public void add(Node node) {
        this.subElements.add(node);
    }

    public void remove(Node node) {
        for (Iterator<Node> iter = subElements.iterator();
             iter.hasNext(); ) {
            Node f = (Node) iter.next();
            if (f instanceof Composite) {
                ((Composite) f).remove(node);
            }
        }
        subElements.remove(node);
    }

    @Override
    public void operation() {
        String formatString;
        level++;
        formatString = "%" + (level * 2) + "s";
        System.out.printf(formatString, "");
        System.out.println("+ " + super.getName() + "");
        for (Iterator<Node> iter = subElements.iterator();
             iter.hasNext(); ) {
            Node f = (Node) (iter.next());
            f.operation();
        }
        --level;
    }
}

Leaf类是叶子节点,没有组合,和Composite相反,没有下层节点,代码如下:

package cn.lut.curiezhang.designpattern.composite;

public class Leaf extends Node {
    public Leaf (String name)
    {
        super (name);
    }

    public void operation()
    {
        String formatString;
        formatString = "%" + (level * 2) + "s";
        System.out.printf (formatString, "");
        System.out.println (" - " + super.getName());
    }
}

有了基本的组合模式框架,就可以构造树形结构,代码如下:

package cn.lut.curiezhang.designpattern.composite;

/**
 * Hello world!
 *
 */
public class Client
{
    public static void main( String[] args )
    {
        System.out.println ("测试组合模式");
        System.out.println ("");

        Composite comp = new Composite ("组合层 1");
        Composite comp11 =
                new Composite ("组合层 11");
        Composite comp12 =
                new Composite ("组合层 12");
        Composite comp121 =
                new Composite ("组合层 121");

        comp.add (comp11);
        comp.add (comp12);

        comp12.add (comp121);

        Leaf leaf111 = new Leaf ("叶111");
        Leaf leaf112 = new Leaf ("叶112");

        Leaf leaf121 = new Leaf ("叶121");
        Leaf leaf122 = new Leaf ("叶122");
        Leaf leaf123 = new Leaf ("叶123");

        Leaf leaf1211 = new Leaf ("叶1211");

        comp11.add (leaf111);
        comp11.add (leaf112);

        comp12.add (leaf121);
        comp12.add (leaf122);
        comp12.add (leaf123);

        comp121.add (leaf1211);

        System.out.println("第1次输出组合操作");
        System.out.println();
        comp.operation();

        comp12.remove (leaf122);
        comp12.remove (comp121);

        System.out.println();
        System.out.println("第2次输出组合操作");
        System.out.println();
        comp.operation();
    }
}

代码执行结果如下图所示:
result
代码实现就是这样的,下面来看看上面设计模式的基本结构,通过类图了解其基本构成,如下图所示:
类图
了解了其基本结构,就需要搞清楚这些类是怎么样来完成交互的,也就是这些对象之间是如何协作的?就通过顺序图来了解其工作过程,这里的交互只绘制了其中的一部分,其他的部分和其类似,如下图所示:
顺序图
请注意其交互过程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值