了解设计模式 之 结构模式(三) -- 组合模式

3. 组合模式(Composite Pattern)

组合模式可以让我们把对象按照树状结构进行组织,可以想象成菜单的概念,菜单下面有子菜单,也会有菜单项,使用了组合模式,我们可以在"子菜单"(组合对象)和"菜单项"(个体对象)上使用相同的操作,也就是说在多数的情况下是不用去区分它们的。

我们还是来举个例子,就是上边说的菜单的例子,我们来建立的一个结构来表示菜单,子菜单和菜单项的组合。

首先定义一个菜单组件的抽象基类,它定义了菜单操作的基本方法,比如#add(),#remove(),#getChild();另外还定义了菜单的行为方法,#getName(),printMenu()。

	/**
* 抽象菜单组件基类<br>
*
* @author archer
*
*/
public abstract class MenuComponent {

/**
* 增加菜单组件(可能是菜单项或者子菜单)<br>
*
* @param menuComponent
*/
public void add(MenuComponent menuComponent) {
throw new UnsupportedOperationException();
}

/**
* 移除菜单组件<br>
*
* @param menuComponent
*/
public void remove(MenuComponent menuComponent) {
throw new UnsupportedOperationException();
}

/**
* 返回子菜单组件<br>
*
* @param i
* @return
*/
public MenuComponent getChild(int i) {
throw new UnsupportedOperationException();
}

/**
* 返回菜单项目或者菜单的名字<br>
*
* @return
*/
public String getName() {
throw new UnsupportedOperationException();
}

/**
* 打印菜单<br>
*
*/
public void printMenu() {
throw new UnsupportedOperationException();
}
}


接下来就是菜单项和菜单类了,它们都是MenuComponent的子类。

	/**
* 菜单项<br>
*
* @author archer
*
*/
public class MenuItem extends MenuComponent {
private String name = null;

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

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

@Override
public void printMenu() {
System.out.println("\t" + this.getName());
}
}

/**
* 菜单<br>
*
* @author archer
*
*/
public class Menu extends MenuComponent {
private List<MenuComponent> menuComponents = new ArrayList<MenuComponent>();

private String name = null;

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

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

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

@Override
public MenuComponent getChild(int i) {
return menuComponents.get(i);
}

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

@Override
public void printMenu() {
System.out.println(this.getName());
System.out.println("--------------------");

// 这里用到了Iterator模式
Iterator<MenuComponent> iter = menuComponents.iterator();

while (iter.hasNext()) {
MenuComponent component = iter.next();
component.printMenu();
}

}

}


通过这种方式,我们就可以在实现一种"整体 -- 局部"关系的同时,又实现了对组合对象与单一对象的统一对待,简化了编程。

接下来可以看一下使用上边例子的客户端代码,这个客户端模拟了eclipse的菜单。

public class Client {

public static void main(String[] args) {
// 总菜单
MenuComponent allMenu = new Menu("Eclipse Menu DEMO");

// "File"子菜单
MenuComponent fileMenu = new Menu("File");

// "New"子菜单
MenuComponent newMenu = new Menu("New");

// "New"的菜单项
MenuComponent EAPMenuItem = new MenuItem("Enterprise Application Project");
MenuComponent DWPMenuItem = new MenuItem("Dynamic Web Project");
MenuComponent EJBMenuItem = new MenuItem("EJB Project");

newMenu.add(EAPMenuItem);
newMenu.add(DWPMenuItem);
newMenu.add(EJBMenuItem);

fileMenu.add(newMenu);

// "Edit"子菜单
MenuComponent editMenu = new Menu("Edit");

// "Edit"的菜单项
MenuComponent CutMenuItem = new MenuItem("Cut");
MenuComponent CopyMenuItem = new MenuItem("Copy");
MenuComponent PasteMenuItem = new MenuItem("Paste");

editMenu.add(CutMenuItem);
editMenu.add(CopyMenuItem);
editMenu.add(PasteMenuItem);

allMenu.add(fileMenu);
allMenu.add(editMenu);

// 打印菜单
allMenu.printMenu();
}

}


它的运行结果如下:

Eclipse Menu DEMO
--------------------
File
--------------------
New
--------------------
Enterprise Application Project
Dynamic Web Project
EJB Project
Edit
--------------------
Cut
Copy
Paste


这样,组合模式就基本讲解完了,最后给出组合模式的类图:

[img]http://zddava.iteye.com/upload/attachment/79156/d08c4481-3087-330b-834c-ec589cd01101.jpg[/img]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值