组合模式

  组合模式允许你将对象组合成树形结构来表现“整体部分”层次结构,组合能让用户以一致的方式来处理个别对象和组合对象。

  以菜单为例,因为子菜单的存在,所以当遍历菜单时,会遇到个别对象(菜单项)和对象组合(子菜单)。

  还好有组合模式。。。

  现在创建一个组件接口来作为菜单和菜单项的共同接口,让我们能够用统一的做法来处理菜单和菜单项。换句话说,我们可以针对菜单和菜单项调用相同的方法。。。But,菜单组件好像扮演了两个角色,是的,确实扮演了两个角色,Y?

  组合模式以单一责任设计原则换取透明性。通过让组件的接口同时包含一些管理子节点和叶节点的操作,客户就可以将组合和叶节点一视同仁。也就是说,一个元素究竟是叶节点还是组合,对客户是透明的。

  因为最好能够为这些方法提供默认的实现,so。。。抽象类的干活。。。

  代码示例:

public abstract class MenuComponent
{
    public void Add (MenuComponent menuComponent)
    {
        throw new Exception();
    }

    public void Remove(MenuComponent menuComponent)
    {
        throw new Exception();
    }

    public string getName()
    {
        throw new Exception();
    }

    public boolean IsVeg ()
    {
        throw new Exception();
    }

    public void print()
    {
        throw new Exception();
    }
}

  因为有些方法只对菜单项有意义,另一些方法只对菜单有意义,默认实现是抛出异常,这样,若菜单(项)不支持某个方法,直接继承默认实现就OK了。

  下面实现菜单项的类,该类只要实现对它有意义的方法即可:

public class MenuItem extends MenuComponent
{
    string name;
    boolean veg;

    public MenuItem(string name, boolean veg)
    {
        this.name = name;
        this.veg = veg;
    }

    public string getName()
    {
        return name;
    }

    public boolean IsVeg()
    {
        return veg;
    }

    public void print()
    {
        system.out.print("this is " + getName());
    }
}

  下面实现菜单的类,同样,该类只要实现对它有意义的方法即可:

public class Menu extends MenuComponent
{
    string name;
    ArrayList menuComponents = new ArrayList();

    public Menu(string name)
    {
        this.name = name;
    }

    public string getName()
    {
        return name;
    }

    public void Add(MenuComponent menuComponent)
    {
        menuComponents.add(menuComponent);
    }

    public void Remove(MenuComponent menuComponent)
    {
        menuComponents.remove(menuComponent);
    }

    public void print()
    {
        system.out.print("this is " + getName() + "菜单,包含:");

        // 该部分采用了迭代器模式
        Iterator iterator = menuComponents.iterator();   
        while(iterator.hasNext())
        {
            MenuComponent menuComponent = (MenuComponent) iterator.next();
            menuComponent.print()     // 递归
        }
    }
}

。。。。。。

  这样我们可以使用menuComponent来处理菜单和菜单项了,而不必去理会该对象是菜单项(个别对象)还是菜单(组合对象)。。。

原文地址:https://www.cnblogs.com/hachun/p/3625304.html