命令模式之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);
}
}
浙公网安备 33010602011771号