命令模式之2 Invoker Vs. Client

当程序中直接编写下达命令的语句如new Cmd1().execute()时。一般会将调用者与客户类合二为一

在GUI程序中。下达命令的语句通常包括在底层框架中。或者说底层框架包括了调用者。这时程序猿编写的程序都是客户类。

GUI程序中,由系统作为命令调用者在某种界面事件发生时自己主动调用命令。


以下的演示程序中使用了button、下拉菜单(JMenuBar-JMenu- JMenuItem)和弹出菜单(JPopupMenu),而JButton 、JMenuItem和JPopupMenu均能够通过其构造器注入一个Action命令。(依赖注入

以下将编写两个AbstractAction的子类,它们将被注入到对应的控件中。

值得注意的是,详细命令类自己实现全部功能,不须要额外的接收者。在此情况下。既能够说应用了命令模式(编写了两个子命令)。也能够说简单的应用了回调(编写了两个包括回调函数的类)。

yqj2065个人觉得,命令模式的概念还是小一点好:详细命令指定运行者(能够是抽象类型)和被调用的方法。将C/S结构的C与S解耦。

GoF的:“将(client的)请求封装为一个对象,从而使你可用不同的请求对客户进行參数化”。过于泛泛而谈。

“将(client的)请求封装为一个对象",參见方法类型化,是Java接口的一般意图;客户下达的cmd.exe(),在多态的场合都是”用不同的请求对客户进行參数化“。当不须要接收者的时候,我们甚至能够把AbstractAction的actionPerformed(ActionEvent evt)视为一个策略,也是能够的,难道我们说此例程使用了策略模式??

无论怎么说,GUI中的这样的应用。是命令模式的典型案例。

假设你的程序中多处使用某种button如Exit。能够使用命令模式编写一个命令。而不是随地使用匿名类

例程 3-22命令
package method.command.gui;
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
class SubmitAction extends AbstractAction {
   private Component target;
   public SubmitAction(String name, Icon icon, Component t){
       putValue(Action.NAME, name);
       putValue(Action.SMALL_ICON, icon);
       putValue(Action.SHORT_DESCRIPTION, name + " the program");
       target = t;
   }    
   @Override public void actionPerformed(ActionEvent evt) {
       JOptionPane.showMessageDialog(target, "submit action ");
   }
}
class ExitAction extends AbstractAction {
   private Component target;
   public ExitAction(String name, Icon icon, Component t){
       putValue(Action.NAME, name);
       putValue(Action.SMALL_ICON, icon);
       putValue(Action.SHORT_DESCRIPTION, name + " the program");
       target = t;
   }    
   @Override public void actionPerformed(ActionEvent evt) {
       int answer = JOptionPane.showConfirmDialog(target, "Are you sure you want to exit? ", "Confirmation",
                           JOptionPane.YES_NO_OPTION);
       if ( answer == JOptionPane.YES_OPTION)  System.exit(0); 
   }
}
public class Test extends JFrame{
    Test() {
        Action ea = new ExitAction("Exit", null, this);
        Action sa = new SubmitAction("Submit", null, this);
        //下拉菜单(JMenuBar-JMenu- JMenuItem)
        JMenuBar bar = new JMenuBar();
        JMenu mn_demo= new JMenu("Demo");
        mn_demo.add(new JMenuItem(sa));
        mn_demo.add(new JMenuItem(ea));
        bar.add(mn_demo);
        this.setJMenuBar(bar);
        //JPopupMenu
        final JPopupMenu pop = new JPopupMenu("PopMenu");
        pop.add(sa);
        pop.add(ea);
        //
        addMouseListener(new MouseAdapter() {
            public void mousePressed(MouseEvent e) {
                showPopup(e);
            } 
            public void mouseReleased(MouseEvent e) {
                showPopup(e);
            }
            private void showPopup(MouseEvent e) {
                if (e.isPopupTrigger()) {
                    pop.show(e.getComponent(),e.getX(), e.getY());
                }
            }
        });
        JPanel jp = new JPanel();
        JButton subbtn = new JButton(sa);
        JButton exitbtn = new JButton(ea);
        jp.add(subbtn);
        jp.add(exitbtn);        
        Container con = getContentPane();
        con.add(jp, "South");

        setTitle("Command pattern example");
        setSize(300,200);
        setVisible(true);
    }
}


posted on 2017-06-01 08:33  yjbjingcha  阅读(172)  评论(0编辑  收藏  举报

导航