Command(命令)模式

  让方法运行的最常见方式调用之。但是在很多情况下,我们不能控制和提供方法执行的时机或者上下文。 在这些情况下,可以把方法封装在对象中。通过在对象中存储调用方法所需的信息,就可以让客户端或者服务决定何时调用这个方法。

  Commmand模式的意图是把请求封装在对象中

 

1.经典范例:菜单命令

  支持菜单的工具集通常都会用到Command模式。每个菜单项都需要配置一个对象,当用户单击它时,可以执行所绑定的对象。这种设计思想使GUI程序逻辑和应用逻辑可以分离开。Swing库就采用这种方法,允许把ActionListener与每个JmenuItem关联起来。

  我们该如何安排才能让一个类在用户单击菜单时调用对应的方法呢?解决的方法就是应用多态性,具体做法如下:首先将操作的名称固定,然后针对不同的类给出不同的实现。对于JMenuItem类而言,该操作就是actionPerformed()。当用户选择某个菜单项的时候,JMenuItem对象就调用其监听器对象的actionPerformed()方法。

 

突破题:java的菜单机制使得Command模式可以很容易地应用于菜单的制作,但是我们并不一定要应用Command模式来组织代码。事实上,在应用程序的开发过程中,通常会用单个对象来监听GUI中的所有事件,请问这种做法遵循了哪一种设计模式?

答:Java Swing应用程序通常应用中介者模式,注册单个对象来接收所有的GUI事件。该对象可以仲裁图形组件的交互,并将用户的输入转换为控制业务域对象的命令。

 当我们在开发Swing应用程序的时候,我们可能会注册单个对象来监听应用程序中的所有GUI事件,特别是在GUI组件交互的时候。不过,对于菜单而言,这并不是最佳的设计模式。如果我们用单个对象作为所有GUI事件的监听器,那么当有事件发生的时候,该对象必须查询出产生事件的GUI对象。而如果在应用程序中有许多菜单项,且它们都对应不同的操作,那么我们最好是应用command模式。  

 当用户选择某菜单项的时候,调用的方法是actionPerformed()。当你创建该菜单项时,可以使用对应于特定命令行为的actionPerformed()方法,给它绑定一个监听器对象(ActionListener)。我们可以定义一个新类来实现这个小功能;不过,更好的做法是,直接使用一个匿名类来实现。

 com.oozinoz.visualization包中的Visualization2类提供了一个“文件”菜单条,包括“Save as ...”,“Restore from ...“两个菜单项。它们分别注册了一个监听器,用于监听用户的单击事件。这两个监听器分别实现了actionPerformed()方法,并分别调用了Visualization2类的save()方法和load()方法。

package com.oozinoz.visualization;
import java.awt.event.*:
import javax.swing.*;
import com.oozinoz.ui.*;
public class Visualization2 extends Visualization
{
	public static void main(String[] args)
	{
		Visualization2 panel = new Visualization2(UI.NORMAL);
		JFrame frame = SwingFacade.launch(panel,"Operational Model");
		frame.setJMenuBar(panel.menus());
		frame.setVisible(true);
	}

	public Visualization2(UI ui){
		super(ui);
	}

	public JMenuBar menus(){
		JManuBar menuBar = new JMenuBar();

		JMenu menu = new JMenu("File");
		menuBar.add(menu);

		JMenuItem menuItem = new JMenuItem("Save As...");
		menuItem.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				save();
			}
		});

		JMenuItem menuItem = new JMenuItem("Restore From...");
		menutItem.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				restore();
			}
		});

		menu.add(menuItem);
		return menuBar;
	}

	public void save(){
		try {
            mediator.save(this);
        } catch (Exception ex) {
            System.out.println("Failed save: " + ex.getMessage());
        }
	}

	public void restore(){
		try {
            mediator.restore(this);
        } catch (Exception ex) {
            System.out.println("Failed restore: " + ex.getMessage());
        }
	}
}

 

 当为一个菜单添加各种命令之后,你还必须将命令应用于其他开发者提供的上下文:Java菜单框架。在Command模式的某些应用场合,你还必须承担上下文开发者的角色,创建命令执行的上下文。例如,我们可能会提供计时服务来记录方法的执行时间。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值