Java/Design Pattern/Command Pattern
Содержание
Command Pattern 2 in Java
<source lang="java">
//[C] 2002 Sun Microsystems, Inc.--- import java.awt.Container; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.Serializable; import java.util.Calendar; import java.util.Date; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JTextArea; import javax.swing.JTextField;
public class RunCommandPattern {
private static Calendar dateCreator = Calendar.getInstance(); public static void main(String [] arguments){ System.out.println("Example for the Command pattern"); System.out.println(); System.out.println("This sample will use a command class called"); System.out.println(" ChangeLocationCommand to update the location"); System.out.println(" of an Appointment object."); System.out.println("The ChangeLocationCommand has the additional"); System.out.println(" ability to undo and redo commands, so it can"); System.out.println(" set the locaition back to its original value,"); System.out.println(" if desired."); System.out.println(); System.out.println("Creating an Appointment for use in the demo"); Contact [] people = { new ContactImpl(), new ContactImpl() }; Appointment appointment = new Appointment("Java Twister Semi-Finals", people, new LocationImpl(""), createDate(2001, 10, 31, 14, 30), createDate(2001, 10, 31, 14, 31)); System.out.println("Creating the ChangeLocationCommand"); ChangeLocationCommand cmd = new ChangeLocationCommand(); cmd.setAppointment(appointment); System.out.println("Creating the GUI"); CommandGui application = new CommandGui(cmd); application.setAppointment(appointment); cmd.setLocationEditor(application); application.createGui(); } public static Date createDate(int year, int month, int day, int hour, int minute){ dateCreator.set(year, month, day, hour, minute); return dateCreator.getTime(); }
} class CommandGui implements ActionListener, LocationEditor{
private JFrame mainFrame; private JTextArea display; private JTextField updatedLocation; private JButton update, undo, redo, exit; private JPanel controlPanel, displayPanel, editorPanel; private UndoableCommand command; private Appointment appointment; public CommandGui(UndoableCommand newCommand){ command = newCommand; } public void setAppointment(Appointment newAppointment){ appointment = newAppointment; } public void createGui(){ mainFrame = new JFrame("Command Pattern Example"); Container content = mainFrame.getContentPane(); content.setLayout(new BoxLayout(content, BoxLayout.Y_AXIS)); editorPanel = new JPanel(); editorPanel.add(new JLabel("Location")); updatedLocation = new JTextField(20); editorPanel.add(updatedLocation); content.add(editorPanel); displayPanel = new JPanel(); display = new JTextArea(10, 40); display.setEditable(false); displayPanel.add(display); content.add(displayPanel); controlPanel = new JPanel(); update = new JButton("Update Location"); undo = new JButton("Undo Location"); redo = new JButton("Redo Location"); exit = new JButton("Exit"); controlPanel.add(update); controlPanel.add(undo); controlPanel.add(redo); controlPanel.add(exit); content.add(controlPanel); update.addActionListener(this); undo.addActionListener(this); redo.addActionListener(this); exit.addActionListener(this); refreshDisplay(); mainFrame.addWindowListener(new WindowCloseManager()); mainFrame.pack(); mainFrame.setVisible(true); } public void actionPerformed(ActionEvent evt){ Object originator = evt.getSource(); if (originator == update){ executeCommand(); } if (originator == undo){ undoCommand(); } if (originator == redo){ redoCommand(); } else if (originator == exit){ exitApplication(); } } private class WindowCloseManager extends WindowAdapter{ public void windowClosing(WindowEvent evt){ exitApplication(); } } public Location getNewLocation(){ return new LocationImpl(updatedLocation.getText()); } private void executeCommand(){ command.execute(); refreshDisplay(); } private void undoCommand(){ command.undo(); refreshDisplay(); } private void redoCommand(){ command.redo(); refreshDisplay(); } private void refreshDisplay(){ display.setText(appointment.toString()); } private void exitApplication(){ System.exit(0); }
} interface Command{
public void execute();
} interface Contact extends Serializable{
public static final String SPACE = " "; public String getFirstName(); public String getLastName(); public String getTitle(); public String getOrganization(); public void setFirstName(String newFirstName); public void setLastName(String newLastName); public void setTitle(String newTitle); public void setOrganization(String newOrganization);
} class ContactImpl implements Contact{
private String firstName; private String lastName; private String title; private String organization; public static final String EOL_STRING = System.getProperty("line.separator"); public ContactImpl(){ } public ContactImpl(String newFirstName, String newLastName, String newTitle, String newOrganization){ firstName = newFirstName; lastName = newLastName; title = newTitle; organization = newOrganization; } public String getFirstName(){ return firstName; } public String getLastName(){ return lastName; } public String getTitle(){ return title; } public String getOrganization(){ return organization; } public void setFirstName(String newFirstName){ firstName = newFirstName; } public void setLastName(String newLastName){ lastName = newLastName; } public void setTitle(String newTitle){ title = newTitle; } public void setOrganization(String newOrganization){ organization = newOrganization; } public String toString(){ return firstName + " " + lastName; }
} class Appointment{
private String reason; private Contact[] contacts; private Location location; private Date startDate; private Date endDate; public Appointment(String reason, Contact[] contacts, Location location, Date startDate, Date endDate){ this.reason = reason; this.contacts = contacts; this.location = location; this.startDate = startDate; this.endDate = endDate; } public String getReason(){ return reason; } public Contact[] getContacts(){ return contacts; } public Location getLocation(){ return location; } public Date getStartDate(){ return startDate; } public Date getEndDate(){ return endDate; } public void setLocation(Location location){ this.location = location; } public String toString(){ return "Appointment:" + "\n Reason: " + reason + "\n Location: " + location + "\n Start: " + startDate + "\n End: " + endDate + "\n"; }
} interface Location extends Serializable{
public String getLocation(); public void setLocation(String newLocation);
} class ChangeLocationCommand implements UndoableCommand{
private Appointment appointment; private Location oldLocation; private Location newLocation; private LocationEditor editor; public Appointment getAppointment(){ return appointment; } public void setAppointment(Appointment appointment){ this.appointment = appointment; } public void setLocationEditor(LocationEditor locationEditor){ editor = locationEditor; } public void execute(){ oldLocation = appointment.getLocation(); newLocation = editor.getNewLocation(); appointment.setLocation(newLocation); } public void undo(){ appointment.setLocation(oldLocation); } public void redo(){ appointment.setLocation(newLocation); }
} interface LocationEditor{
public Location getNewLocation();
} class LocationImpl implements Location{
private String location; public LocationImpl(){ } public LocationImpl(String newLocation){ location = newLocation; } public String getLocation(){ return location; } public void setLocation(String newLocation){ location = newLocation; } public String toString(){ return location; }
} interface UndoableCommand extends Command{
public void undo(); public void redo();
}
</source>
Command Pattern - Example: FTP GUI
<source lang="java">
/* Software Architecture Design Patterns in Java by Partha Kuchana Auerbach Publications
- /
import java.awt.BorderLayout; import java.awt.Container; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.DefaultListModel; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.ListSelectionModel; import javax.swing.SwingUtilities; import javax.swing.UIManager; import com.sun.java.swing.plaf.windows.WindowsLookAndFeel; public class FTPGUI extends JFrame {
public static final String newline = "\n"; public static final String UPLOAD = "Upload"; public static final String DOWNLOAD = "Download"; public static final String DELETE = "Delete"; public static final String EXIT = "Exit"; private JPanel pnlFTPUI; private JList localList; private JList remoteList; private DefaultListModel defLocalList, defRemoteList; private UploadButton btnUpload; private DownloadButton btnDownload; private DeleteButton btnDelete; public FTPGUI() throws Exception { super("Command Pattern - Example"); // Create controls defLocalList = new DefaultListModel(); defRemoteList = new DefaultListModel(); localList = new JList(defLocalList); remoteList = new JList(defRemoteList); pnlFTPUI = new JPanel(); localList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); localList.setSelectedIndex(-1); JScrollPane spLocalList = new JScrollPane(localList); remoteList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); remoteList.setSelectedIndex(-1); JScrollPane spRemoteList = new JScrollPane(remoteList); //Create Labels JLabel lblLocalList = new JLabel("Local List:"); JLabel lblRemoteList = new JLabel("Remote List:"); JLabel lblSpacer = new JLabel(" "); //Create buttons btnUpload = new UploadButton(FTPGUI.UPLOAD); btnUpload.setMnemonic(KeyEvent.VK_U); btnDownload = new DownloadButton(FTPGUI.DOWNLOAD); btnDownload.setMnemonic(KeyEvent.VK_N); btnDelete = new DeleteButton(FTPGUI.DELETE); btnDelete.setMnemonic(KeyEvent.VK_D); ExitButton btnExit = new ExitButton(FTPGUI.EXIT); btnExit.setMnemonic(KeyEvent.VK_X); buttonHandler vf = new buttonHandler(); btnUpload.addActionListener(vf); btnDownload.addActionListener(vf); btnDelete.addActionListener(vf); btnExit.addActionListener(vf); JPanel lstPanel = new JPanel(); GridBagLayout gridbag2 = new GridBagLayout(); lstPanel.setLayout(gridbag2); GridBagConstraints gbc2 = new GridBagConstraints(); lstPanel.add(lblLocalList); lstPanel.add(lblRemoteList); lstPanel.add(spLocalList); lstPanel.add(spRemoteList); lstPanel.add(lblSpacer); gbc2.gridx = 0; gbc2.gridy = 0; gridbag2.setConstraints(lblLocalList, gbc2); gbc2.gridx = 1; gbc2.gridy = 0; gridbag2.setConstraints(lblSpacer, gbc2); gbc2.gridx = 5; gbc2.gridy = 0; gridbag2.setConstraints(lblRemoteList, gbc2); gbc2.gridx = 0; gbc2.gridy = 1; gridbag2.setConstraints(spLocalList, gbc2); gbc2.gridx = 5; gbc2.gridy = 1; gridbag2.setConstraints(spRemoteList, gbc2); //----------------------------------- //For layout purposes, put the buttons in a separate panel JPanel buttonPanel = new JPanel(); //---------------------------------------------- GridBagLayout gridbag = new GridBagLayout(); buttonPanel.setLayout(gridbag); GridBagConstraints gbc = new GridBagConstraints(); buttonPanel.add(lstPanel); buttonPanel.add(btnUpload); buttonPanel.add(btnDownload); buttonPanel.add(btnDelete); buttonPanel.add(btnExit); gbc.insets.top = 5; gbc.insets.bottom = 5; gbc.insets.left = 5; gbc.insets.right = 5; gbc.anchor = GridBagConstraints.WEST; gbc.gridx = 1; gbc.gridy = 0; gridbag.setConstraints(btnUpload, gbc); gbc.gridx = 2; gbc.gridy = 0; gridbag.setConstraints(btnDownload, gbc); gbc.gridx = 3; gbc.gridy = 0; gridbag.setConstraints(btnDelete, gbc); gbc.gridx = 4; gbc.gridy = 0; gridbag.setConstraints(btnExit, gbc); gbc.gridx = 0; gbc.gridy = 1; gridbag.setConstraints(lstPanel, gbc); gbc.anchor = GridBagConstraints.EAST; gbc.insets.left = 2; gbc.insets.right = 2; gbc.insets.top = 40; //**************************************************** //Add the buttons and the log to the frame Container contentPane = getContentPane(); contentPane.add(lstPanel, BorderLayout.CENTER); contentPane.add(buttonPanel, BorderLayout.SOUTH); initialize(); try { UIManager.setLookAndFeel(new WindowsLookAndFeel()); SwingUtilities.updateComponentTreeUI(FTPGUI.this); } catch (Exception ex) { System.out.println(ex); } } private void initialize() { // fill some test data here into the listbox. defLocalList.addElement("first.html"); defLocalList.addElement("second.html"); defLocalList.addElement("third.html"); defLocalList.addElement("fourth.html"); defLocalList.addElement("fifth.html"); defLocalList.addElement("Design Patterns 1.html"); defRemoteList.addElement("sixth.html"); defRemoteList.addElement("seventh.html"); defRemoteList.addElement("eighth.html"); defRemoteList.addElement("ninth.html"); defRemoteList.addElement("Design Patterns 2.html"); } public static void main(String[] args) throws Exception { JFrame frame = new FTPGUI(); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); //frame.pack(); frame.setSize(450, 300); frame.setVisible(true); } class buttonHandler implements ActionListener { public void actionPerformed(ActionEvent e) { CommandInterface CommandObj = (CommandInterface) e.getSource(); CommandObj.processEvent(); } } interface CommandInterface { public void processEvent(); } class UploadButton extends JButton implements CommandInterface { public void processEvent() { int index = localList.getSelectedIndex(); String selectedItem = localList.getSelectedValue().toString(); ((DefaultListModel) localList.getModel()).remove(index); ((DefaultListModel) remoteList.getModel()).addElement(selectedItem); } public UploadButton(String name) { super(name); } } class DownloadButton extends JButton implements CommandInterface { public void processEvent() { int index = remoteList.getSelectedIndex(); String selectedItem = remoteList.getSelectedValue().toString(); ((DefaultListModel) remoteList.getModel()).remove(index); ((DefaultListModel) localList.getModel()).addElement(selectedItem); } public DownloadButton(String name) { super(name); } } class DeleteButton extends JButton implements CommandInterface { public void processEvent() { int index = localList.getSelectedIndex(); if (index >= 0) { ((DefaultListModel) localList.getModel()).remove(index); } index = remoteList.getSelectedIndex(); if (index >= 0) { ((DefaultListModel) remoteList.getModel()).remove(index); } } public DeleteButton(String name) { super(name); } } class ExitButton extends JButton implements CommandInterface { public void processEvent() { System.exit(1); } public ExitButton(String name) { super(name); } }
}// end of class
</source>
Command pattern in Java 1
<source lang="java">
/* The Design Patterns Java Companion Copyright (C) 1998, by James W. Cooper IBM Thomas J. Watson Research Center
- /
import java.awt.Button; import java.awt.Color; import java.awt.FileDialog; import java.awt.Frame; import java.awt.Menu; import java.awt.MenuBar; import java.awt.MenuItem; import java.awt.Panel; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; public class ActionCommand extends Frame {
Menu mnuFile; MenuItem mnuOpen, mnuExit; Button btnRed; Panel p; Frame fr; //----------------------------------------- public ActionCommand() { super("Frame without commands"); fr = this; //sae cop of this frame MenuBar mbar = new MenuBar(); setMenuBar(mbar); mnuFile = new Menu("File", true); mbar.add(mnuFile); mnuOpen = new MenuItem("Open..."); mnuFile.add(mnuOpen); mnuExit = new MenuItem("Exit"); mnuFile.add(mnuExit); mnuOpen.addActionListener(new fileOpen()); mnuExit.addActionListener(new fileExit()); btnRed = new Button("Red"); p = new Panel(); add(p); p.add(btnRed); btnRed.addActionListener(new btnRed()); setBounds(100, 100, 200, 100); setVisible(true); } //----------------------------------------- private void exitClicked() { System.exit(0); } //----------------------------------------- static public void main(String argv[]) { new ActionCommand(); } //=====----====--inner classes---=====---- class fileOpen implements ActionListener { public void actionPerformed(ActionEvent e) { FileDialog fDlg = new FileDialog(fr, "Open a file", FileDialog.LOAD); fDlg.show(); } } //------------------------------------- class btnRed implements ActionListener { public void actionPerformed(ActionEvent e) { p.setBackground(Color.red); } } //------------------------------------- class fileExit implements ActionListener { public void actionPerformed(ActionEvent e) { System.exit(0); } }
} //=====================================
</source>
Command pattern in Java 2
<source lang="java">
/* The Design Patterns Java Companion Copyright (C) 1998, by James W. Cooper IBM Thomas J. Watson Research Center
- /
import java.awt.Button; import java.awt.Color; import java.awt.FileDialog; import java.awt.Frame; import java.awt.Menu; import java.awt.MenuBar; import java.awt.MenuItem; import java.awt.Panel; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; interface Command {
public void Execute();
} public class TestCommand extends Frame implements ActionListener {
Menu mnuFile; fileOpenCommand mnuOpen; fileExitCommand mnuExit; btnRedCommand btnRed; Panel p; Frame fr; //----------------------------------------- public TestCommand() { super("Frame without commands"); fr = this; //save frame object MenuBar mbar = new MenuBar(); setMenuBar(mbar); mnuFile = new Menu("File", true); mbar.add(mnuFile); mnuOpen = new fileOpenCommand("Open..."); mnuFile.add(mnuOpen); mnuExit = new fileExitCommand("Exit"); mnuFile.add(mnuExit); mnuOpen.addActionListener(this); mnuExit.addActionListener(this); btnRed = new btnRedCommand("Red"); p = new Panel(); add(p); p.add(btnRed); btnRed.addActionListener(this); setBounds(100, 100, 200, 100); setVisible(true); } //----------------------------------------- public void actionPerformed(ActionEvent e) { Command obj = (Command) e.getSource(); obj.Execute(); } //----------------------------------------- static public void main(String argv[]) { new TestCommand(); } //====----====-----inner class----=====---- class btnRedCommand extends Button implements Command { public btnRedCommand(String caption) { super(caption); } public void Execute() { p.setBackground(Color.red); } } //------------------------------------------ class fileOpenCommand extends MenuItem implements Command { public fileOpenCommand(String caption) { super(caption); } public void Execute() { FileDialog fDlg = new FileDialog(fr, "Open file"); fDlg.show(); } } //------------------------------------------- class fileExitCommand extends MenuItem implements Command { public fileExitCommand(String caption) { super(caption); } public void Execute() { System.exit(0); } }
} //==========================================
</source>
Command pattern in Java 3
<source lang="java">
/* The Design Patterns Java Companion Copyright (C) 1998, by James W. Cooper IBM Thomas J. Watson Research Center
- /
import java.awt.Button; import java.awt.Color; import java.awt.FileDialog; import java.awt.Frame; import java.awt.Menu; import java.awt.MenuBar; import java.awt.MenuItem; import java.awt.Panel; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; interface Command {
public void Execute();
} public class ExtrnCommand extends Frame implements ActionListener {
Menu mnuFile; fileOpenCommand mnuOpen; fileExitCommand mnuExit; btnRedCommand btnRed; Panel p; Frame fr; //----------------------------------------- public ExtrnCommand() { super("Frame with external commands"); fr = this; //save frame object MenuBar mbar = new MenuBar(); setMenuBar(mbar); mnuFile = new Menu("File", true); mbar.add(mnuFile); mnuOpen = new fileOpenCommand("Open...", this); mnuFile.add(mnuOpen); mnuExit = new fileExitCommand("Exit"); mnuFile.add(mnuExit); mnuOpen.addActionListener(this); mnuExit.addActionListener(this); p = new Panel(); add(p); btnRed = new btnRedCommand("Red", p); p.add(btnRed); btnRed.addActionListener(this); setBounds(100, 100, 200, 100); setVisible(true); } //----------------------------------------- public void actionPerformed(ActionEvent e) { Command obj = (Command) e.getSource(); obj.Execute(); } //----------------------------------------- static public void main(String argv[]) { new ExtrnCommand(); }
} //========================================== class btnRedCommand extends Button implements Command {
Panel p; public btnRedCommand(String caption, Panel pnl) { super(caption); p = pnl; } public void Execute() { p.setBackground(Color.red); }
} //------------------------------------------ class fileOpenCommand extends MenuItem implements Command {
Frame fr; public fileOpenCommand(String caption, Frame frm) { super(caption); fr = frm; } public void Execute() { FileDialog fDlg = new FileDialog(fr, "Open file"); fDlg.show(); }
} //------------------------------------------- class fileExitCommand extends MenuItem implements Command {
public fileExitCommand(String caption) { super(caption); } public void Execute() { System.exit(0); }
}
</source>
Command pattern in Java 4
<source lang="java">
/* The Design Patterns Java Companion Copyright (C) 1998, by James W. Cooper IBM Thomas J. Watson Research Center
- /
import java.awt.Button; import java.awt.Color; import java.awt.FileDialog; import java.awt.Frame; import java.awt.Menu; import java.awt.MenuBar; import java.awt.MenuItem; import java.awt.Panel; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; public class InnerCommand extends Frame {
Menu mnuFile; MenuItem mnuOpen, mnuExit; Button btnRed; Panel p; Frame fr; //----------------------------------------- public InnerCommand() { super("Frame without commands"); fr = this; MenuBar mbar = new MenuBar(); setMenuBar(mbar); mnuFile = new Menu("File", true); mbar.add(mnuFile); mnuOpen = new MenuItem("Open..."); mnuFile.add(mnuOpen); mnuExit = new MenuItem("Exit"); mnuFile.add(mnuExit); mnuOpen.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { FileDialog fDlg = new FileDialog(fr, "Open a file", FileDialog.LOAD); fDlg.show(); } }); mnuExit.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { System.exit(0); } }); btnRed = new Button("Red"); p = new Panel(); add(p); p.add(btnRed); btnRed.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { p.setBackground(Color.red); } }); setBounds(100, 100, 200, 100); setVisible(true); } //----------------------------------------- static public void main(String argv[]) { new InnerCommand(); }
} //=====================================
</source>
Command pattern: Shopping
<source lang="java">
/* Software Architecture Design Patterns in Java by Partha Kuchana Auerbach Publications
- /
import java.util.HashMap; public class CommandTest {
public static void main(String[] args) { //Add an item to the CD category //create Receiver objects Item CD = new Item("A Beautiful Mind"); Category catCD = new Category("CD"); //create the command object CommandInterface command = new AddCommand(CD, catCD); //create the invoker ItemManager manager = new ItemManager(); //configure the invoker //with the command object manager.setCommand(command); manager.process(); //Add an item to the CD category CD = new Item("Duet"); catCD = new Category("CD"); command = new AddCommand(CD, catCD); manager.setCommand(command); manager.process(); //Add an item to the New Releases category CD = new Item("Duet"); catCD = new Category("New Releases"); command = new AddCommand(CD, catCD); manager.setCommand(command); manager.process(); //Delete an item from the New Releases category command = new DeleteCommand(CD, catCD); manager.setCommand(command); manager.process(); }
} class ItemManager {
CommandInterface command; public void setCommand(CommandInterface c) { command = c; } public void process() { command.execute(); }
} class Item {
private HashMap categories; private String desc; public Item(String s) { desc = s; categories = new HashMap(); } public String getDesc() { return desc; } public void add(Category cat) { categories.put(cat.getDesc(), cat); } public void delete(Category cat) { categories.remove(cat.getDesc()); }
} class DeleteCommand implements CommandInterface {
Item item; Category cat; public DeleteCommand(Item i, Category c) { item = i; cat = c; } public void execute() { item.delete(cat); cat.delete(item); }
} interface CommandInterface {
public void execute();
} class Category {
private HashMap items; private String desc; public Category(String s) { desc = s; items = new HashMap(); } public String getDesc() { return desc; } public void add(Item i) { items.put(i.getDesc(), i); System.out.println("Item "" + i.getDesc() + "" has been added to the "" + getDesc() + "" Category "); } public void delete(Item i) { items.remove(i.getDesc()); System.out.println("Item "" + i.getDesc() + "" has been deleted from the "" + getDesc() + "" Category "); }
} class AddCommand implements CommandInterface {
Item item; Category cat; public AddCommand(Item i, Category c) { item = i; cat = c; } public void execute() { item.add(cat); cat.add(item); }
}
</source>