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

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


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

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

你可能感兴趣的:(eclipse,设计模式,编程,Web,ejb)