首页 > 代码库 > 命令模式之2 Invoker Vs. Client
命令模式之2 Invoker Vs. Client
当程序中直接编写下达命令的语句如new Cmd1().execute()时,通常会将调用者与客户类合二为一;
在GUI程序中,下达命令的语句通常包含在底层框架中,或者说底层框架包含了调用者,这时程序员编写的程序都是客户类。
GUI程序中,由系统作为命令调用者在某种界面事件发生时自动调用命令。
下面的演示程序中使用了按钮、下拉菜单(JMenuBar-JMenu- JMenuItem)和弹出菜单(JPopupMenu),而JButton 、JMenuItem和JPopupMenu均可以通过其构造器注入一个Action命令。(依赖注入)
下面将编写两个AbstractAction的子类,它们将被注入到相应的控件中。
值得注意的是,具体命令类自己实现所有功能,不需要额外的接收者。在此情况下,既可以说应用了命令模式(编写了两个子命令),也可以说简单的应用了回调(编写了两个包含回调函数的类)。yqj2065个人认为,命令模式的概念还是小一点好:具体命令指定执行者(可以是抽象类型)和被调用的方法,将C/S结构的C与S解耦。
GoF的:“将(客户端的)请求封装为一个对象,从而使你可用不同的请求对客户进行参数化”。过于泛泛而谈。“将(客户端的)请求封装为一个对象",参见方法类型化,是Java接口的一般意图;客户下达的cmd.exe(),在多态的场合都是”用不同的请求对客户进行参数化“。当不需要接收者的时候,我们甚至可以把AbstractAction的actionPerformed(ActionEvent evt)视为一个策略,也是可以的,难道我们说此例程使用了策略模式??
不管怎么说,GUI中的这种应用,是命令模式的典型案例。
如果你的程序中多处使用某种按钮如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); } }
命令模式之2 Invoker Vs. Client
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。