Java/Design Pattern/Memento Pattern

Материал из Java эксперт
Перейти к: навигация, поиск

Memento Pattern 2

//[C] 2002 Sun Microsystems, Inc.---
import java.io.Serializable;
import java.util.ArrayList;
public class RunMementoPattern {
  public static void main(String[] arguments) {
    System.out.println("Example for the Memento pattern");
    System.out.println();
    System.out
        .println("This example will use the AddressBook to demonstrate");
    System.out
        .println(" how a Memento can be used to save and restore state.");
    System.out
        .println("The AddressBook has an inner class, AddressBookMemento,");
    System.out
        .println(" that is used to store the AddressBook state... in this");
    System.out.println(" case, its internal list of contacts.");
    System.out.println();
    System.out.println("Creating the AddressBook");
    AddressBook book = new AddressBook();
    System.out.println("Adding Contact entries for the AddressBook");
    book.addContact(new ContactImpl("Peter", "Taggart", "Commander",
        "NSEA Protector", new AddressImpl()));
    book.addContact(new ContactImpl("Tawny", "Madison", "Lieutenant",
        "NSEA Protector", new AddressImpl()));
    book.addContact(new ContactImpl("Dr.", "Lazarus", "Dr.",
        "NSEA Protector", new AddressImpl()));
    book.addContact(new ContactImpl("Tech Sargent", "Chen", "Tech Sargent",
        "NSEA Protector", new AddressImpl()));
    System.out.println("Contacts added. Current Contact list:");
    System.out.println(book);
    System.out.println();
    System.out.println("Creating a Memento for the address book");
    Object memento = book.getMemento();
    System.out
        .println("Now that a Memento exists, it can be used to restore");
    System.out
        .println(" the state of this AddressBook object, or to set the");
    System.out.println(" state of a new AddressBook.");
    System.out.println();
    System.out.println("Creating new entries for the AddressBook");
    book.removeAllContacts();
    book.addContact(new ContactImpl("Jason", "Nesmith", "",
        "Actor"s Guild", new AddressImpl()));
    book.addContact(new ContactImpl("Gwen", "DeMarco", "", "Actor"s Guild",
        new AddressImpl()));
    book.addContact(new ContactImpl("Alexander", "Dane", "",
        "Actor"s Guild", new AddressImpl()));
    book.addContact(new ContactImpl("Fred", "Kwan", "", "Actor"s Guild",
        new AddressImpl()));
    System.out.println("New Contacts added. Current Contact list:");
    System.out.println(book);
    System.out.println();
    System.out
        .println("Using the Memento object to restore the AddressBook");
    System.out.println(" to its original state.");
    book.setMemento(memento);
    System.out.println("AddressBook restored. Current Contact list:");
    System.out.println(book);
  }
}
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);
}
interface Address extends Serializable {
  public static final String EOL_STRING = System
      .getProperty("line.separator");
  public static final String SPACE = " ";
  public static final String COMMA = ",";
  public String getType();
  public String getDescription();
  public String getStreet();
  public String getCity();
  public String getState();
  public String getZipCode();
  public void setType(String newType);
  public void setDescription(String newDescription);
  public void setStreet(String newStreet);
  public void setCity(String newCity);
  public void setState(String newState);
  public void setZipCode(String newZip);
}
class ContactImpl implements Contact {
  private String firstName;
  private String lastName;
  private String title;
  private String organization;
  private Address address;
  public ContactImpl() {
  }
  public ContactImpl(String newFirstName, String newLastName,
      String newTitle, String newOrganization, Address newAddress) {
    firstName = newFirstName;
    lastName = newLastName;
    title = newTitle;
    organization = newOrganization;
    address = newAddress;
  }
  public String getFirstName() {
    return firstName;
  }
  public String getLastName() {
    return lastName;
  }
  public String getTitle() {
    return title;
  }
  public String getOrganization() {
    return organization;
  }
  public Address getAddress() {
    return address;
  }
  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 void setAddress(Address newAddress) {
    address = newAddress;
  }
  public String toString() {
    return firstName + " " + lastName;
  }
}
class AddressImpl implements Address {
  private String type;
  private String description;
  private String street;
  private String city;
  private String state;
  private String zipCode;
  public AddressImpl() {
  }
  public AddressImpl(String newDescription, String newStreet, String newCity,
      String newState, String newZipCode) {
    description = newDescription;
    street = newStreet;
    city = newCity;
    state = newState;
    zipCode = newZipCode;
  }
  public String getType() {
    return type;
  }
  public String getDescription() {
    return description;
  }
  public String getStreet() {
    return street;
  }
  public String getCity() {
    return city;
  }
  public String getState() {
    return state;
  }
  public String getZipCode() {
    return zipCode;
  }
  public void setType(String newType) {
    type = newType;
  }
  public void setDescription(String newDescription) {
    description = newDescription;
  }
  public void setStreet(String newStreet) {
    street = newStreet;
  }
  public void setCity(String newCity) {
    city = newCity;
  }
  public void setState(String newState) {
    state = newState;
  }
  public void setZipCode(String newZip) {
    zipCode = newZip;
  }
  public String toString() {
    return street + EOL_STRING + city + COMMA + SPACE + state + SPACE
        + zipCode + EOL_STRING;
  }
}
class AddressBook {
  private ArrayList contacts = new ArrayList();
  public Object getMemento() {
    return new AddressBookMemento(contacts);
  }
  public void setMemento(Object object) {
    if (object instanceof AddressBookMemento) {
      AddressBookMemento memento = (AddressBookMemento) object;
      contacts = memento.state;
    }
  }
  private class AddressBookMemento {
    private ArrayList state;
    private AddressBookMemento(ArrayList contacts) {
      this.state = contacts;
    }
  }
  public AddressBook() {
  }
  public AddressBook(ArrayList newContacts) {
    contacts = newContacts;
  }
  public void addContact(Contact contact) {
    if (!contacts.contains(contact)) {
      contacts.add(contact);
    }
  }
  public void removeContact(Contact contact) {
    contacts.remove(contact);
  }
  public void removeAllContacts() {
    contacts = new ArrayList();
  }
  public ArrayList getContacts() {
    return contacts;
  }
  public String toString() {
    return contacts.toString();
  }
}





Memento pattern in Java

/*
The Design Patterns Java Companion
Copyright (C) 1998, by James W. Cooper
IBM Thomas J. Watson Research Center
*/
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Vector;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JToggleButton;
import javax.swing.JToolBar;
public class MemDraw extends JFrame implements ActionListener {
  JToolBar tbar;
  Mediator med;
  
  public MemDraw() {
    super("Memento Drawing");
    addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        System.exit(0);
      }
    });
    JPanel jp = new JPanel();
    getContentPane().add(jp);
    med = new Mediator();
    jp.setLayout(new BorderLayout());
    tbar = new JToolBar();
    jp.add("North", tbar);
    RectButton rect = new RectButton(this, med);
    tbar.add(rect);
    UndoButton undo = new UndoButton(this, med);
    tbar.add(undo);
    tbar.addSeparator();
    ClearButton clr = new ClearButton(this, med);
    tbar.add(clr);
    JCanvas canvas = new JCanvas(med);
    jp.add("Center", canvas);
    MouseApp map = new MouseApp(med);
    canvas.addMouseListener(map);
    MouseMoveApp mvap = new MouseMoveApp(med);
    canvas.addMouseMotionListener(mvap);
    setSize(new Dimension(400, 300));
    setVisible(true);
  }
  
  public void actionPerformed(ActionEvent e) {
    Command comd = (Command) e.getSource();
    comd.Execute();
  }
  
  static public void main(String[] argv) {
    new MemDraw();
  }
}
//==============================
class MouseApp extends MouseAdapter {
  Mediator med;
  public MouseApp(Mediator md) {
    super();
    med = md;
  }
  public void mousePressed(MouseEvent e) {
    med.createRect(e.getX(), e.getY());
  }
  public void mouseReleased(MouseEvent e) {
    med.rememberPosition();
  }
}

class MouseMoveApp extends MouseMotionAdapter {
  Mediator med;
  public MouseMoveApp(Mediator md) {
    super();
    med = md;
  }
  public void mouseDragged(MouseEvent e) {
    med.drag(e.getX(), e.getY());
  }
}
class ClearButton extends JButton implements Command {
  Mediator med;
  public ClearButton(ActionListener act, Mediator md) {
    super("C");
    setToolTipText("Clear");
    addActionListener(act);
    med = md;
  }
  
  public void Execute() {
    med.clear();
  }
}
class JCanvas extends JPanel {
  Mediator med;
  public JCanvas(Mediator md) {
    med = md;
    med.registerCanvas(this);
    setBackground(Color.white);
  }
  public void paint(Graphics g) {
    super.paint(g);
    med.reDraw(g);
  }
}
class Mediator {
  boolean startRect;
  boolean rectSelected;
  Vector drawings;
  Vector undoList;
  RectButton rect;
  JPanel canvas;
  visRectangle selectedRectangle;
  public Mediator() {
    startRect = false;
    rectSelected = false;
    drawings = new Vector();
    undoList = new Vector();
  }
  
  public void startRectangle() {
    startRect = true;
  }
  
  public void createRect(int x, int y) {
    unpick(); //make sure no rectangle is selected
    if (startRect) //if rect button is depressed
    {
      Integer count = new Integer(drawings.size());
      undoList.addElement(count); //Save previous drawing list size
      visRectangle v = new visRectangle(x, y);
      drawings.addElement(v); //add new element to list
      startRect = false; //done with this rectangle
      rect.setSelected(false); //unclick button
      canvas.repaint();
    } else
      pickRect(x, y); //if not pressed look for rect to select
  }
  
  public void registerRectButton(RectButton rb) {
    rect = rb;
  }
  
  public void registerCanvas(JPanel p) {
    canvas = p;
  }
  
  private void unpick() {
    rectSelected = false;
    if (selectedRectangle != null) {
      selectedRectangle.setSelected(false);
      selectedRectangle = null;
      repaint();
    }
  }
  
  public void rememberPosition() {
    if (rectSelected) {
      Memento m = new Memento(selectedRectangle);
      undoList.addElement(m);
    }
  }
  
  public void pickRect(int x, int y) {
    //save current selected rectangle to avoid double save of undo
    visRectangle lastPick = selectedRectangle;
    unpick();
    for (int i = 0; i < drawings.size(); i++) {
      visRectangle v = (visRectangle) drawings.elementAt(i);
      if (v.contains(x, y)) //did click inside a rectangle
      {
        selectedRectangle = v; //save it
        rectSelected = true;
        if (selectedRectangle != lastPick) //but don"t save twice
          rememberPosition();
        v.setSelected(true); //turn on handles
        repaint(); //and redraw
      }
    }
  }
  
  public void clear() {
    drawings = new Vector();
    undoList = new Vector();
    rectSelected = false;
    selectedRectangle = null;
    repaint();
  }
  
  private void repaint() {
    canvas.repaint();
  }
  
  public void drag(int x, int y) {
    if (rectSelected) {
      if (selectedRectangle.contains(x, y)) {
        selectedRectangle.move(x, y);
        repaint();
      }
    }
  }
  
  public void reDraw(Graphics g) {
    g.setColor(Color.black);
    for (int i = 0; i < drawings.size(); i++) {
      visRectangle v = (visRectangle) drawings.elementAt(i);
      v.draw(g);
    }
  }
  
  public void undo() {
    if (undoList.size() > 0) {
      //get last element in undo list
      Object obj = undoList.lastElement();
      undoList.removeElement(obj); //and remove it
      //if this is an Integer, the last action was a new rectangle
      if (obj instanceof Integer) {
        //remove last created rectangle
        Object drawObj = drawings.lastElement();
        drawings.removeElement(drawObj);
      }
      //if this is a Memento, the last action was a move
      if (obj instanceof Memento) {
        //get the Memento
        Memento m = (Memento) obj;
        m.restore(); //and restore the old position
      }
      repaint();
    }
  }
}
interface Command {
  public void Execute();
}
class RectButton extends JToggleButton implements Command {
  Mediator med;
  public RectButton(ActionListener act, Mediator md) {
    super("R");
    //setSize(new Dimension(25,25));
    //setBorder(new EmptyBorder(5,5,5,5));
    setToolTipText("Draw rectangle");
    addActionListener(act);
    med = md;
    med.registerRectButton(this);
  }
  
  public void Execute() {
    if (isSelected()) {
      med.startRectangle();
    }
  }
}
class UndoButton extends JButton implements Command {
  Mediator med;
  public UndoButton(ActionListener act, Mediator md) {
    super("U");
    //setSize(new Dimension(25,25));
    //setBorder(new EmptyBorder(5,5,5,5));
    setToolTipText("Undo");
    addActionListener(act);
    med = md;
  }
  
  public void Execute() {
    med.undo();
  }
}
class visRectangle {
  int x, y, w, h;
  Rectangle rect;
  boolean selected;
  public visRectangle(int xpt, int ypt) {
    x = xpt;
    y = ypt;
    w = 40;
    h = 30;
    saveAsRect();
  }
  
  public void setSelected(boolean b) {
    selected = b;
  }
  
  private void saveAsRect() {
    rect = new Rectangle(x - w / 2, y - h / 2, w, h);
  }
  
  public void draw(Graphics g) {
    g.drawRect(x, y, w, h);
    if (selected) {
      g.fillRect(x + w / 2, y - 2, 4, 4);
      g.fillRect(x - 2, y + h / 2, 4, 4);
      g.fillRect(x + w / 2, y + h - 2, 4, 4);
      g.fillRect(x + w - 2, y + h / 2, 4, 4);
    }
  }
  
  public boolean contains(int x, int y) {
    return rect.contains(x, y);
  }
  
  public void move(int xpt, int ypt) {
    x = xpt;
    y = ypt;
    saveAsRect();
  }
}
//===============================================
class Memento {
  visRectangle rect;
  //saved fields- remember internal fields
  //of the specified visual rectangle
  int x, y, w, h;
  public Memento(visRectangle r) {
    rect = r;
    x = rect.x;
    y = rect.y;
    w = rect.w;
    h = rect.h;
  }
  
  public void restore() {
    //restore the internal state of
    //the specified rectangle
    rect.x = x;
    rect.y = y;
    rect.h = h;
    rect.w = w;
  }
}