next up previous contents
Next: Remote(RMI)/Persistent Objects Up: Case Study Previous: Case Study   Contents

Observable/Persistent Objects [74]




\begin{picture}(385,316)(55,484)\thicklines
\put(250,525){\oval(42,22)}
\put(...
...]{\raisebox{0pt}[0pt][0pt]{\twlrm (either SQL or Serialization)}}}
\end{picture}



$\bullet$ Multiple Observer Frames watch the Observable Supplier

$\bullet$ Each Frame registers with the Supplier using a call to addObserver(this)

$\bullet$ Supplier does addElement(observer) to the Vector in Observable

$\bullet$ User presses SUBMIT on a Frame, which mutates() the Supplier

$\bullet$ Supplier modifies the disk using SQL or Java's Serializable interface

$\bullet$ Supplier calls inherited notifyObservers()

$\bullet$ notifyObservers() iterates through Vector, casts, calls update() on Frame

$\bullet$ Each Frame has an update(), which calls the Supplier's accessor methods

$\bullet$ Frame refreshes the screen



Observable/Persistent Classes: Responsibilities [75]



$\bullet$ The following diagrams provide detail about the Class Responsibilities:

$\bullet$ Observable: maintain Vector of registered Observers, notifyObservers() upon mutation

$\bullet$ Observer: interface to enforce ObsFrame to have update() method

$\bullet$ Obsmain: create 2 Suppliers, and $n$ ObsFrames per to watch

$\bullet$ DataBase: perform first 5 (out of 7) steps of JDBC to query database

$\bullet$ ObsFrame: register as Observer, display 4 fields, button causes mutate(), update() causes displaySupplier()

$\bullet$ Supplier: maintain 4 fields, ``is a'' Observable, ``has a'' DataBase, upon construction loadSupplier() from DataBase, upon mutation storeSupplier() to the DataBase and notifyObservers()



Observable/Persistent Supplier Objects: Class Diagrams [76]





\begin{picture}(575,605)(35,215)\thicklines
\put( 35,685){\framebox (165,135)...
...b]{\raisebox{0pt}[0pt][0pt]{\twlrm user:String,password:String)}}}
\end{picture}



DataBase: Construction [77]





\begin{picture}(510,305)(10,500)\thicklines
\put(160,760){\circle{10}}
\put( ...
...ate String url = ''jdbc:mysql://gold.mcs.csueastbay.edu:3306/''}}}
\end{picture}




$\bullet$ DataBase is constructed by the Supplier when it is constructed

$\bullet$ Constructor for DataBase initializes private variables

$\bullet$ Base URL indicates where the server is located and the port it uses

$\bullet$ URL needs to have the database name appended to the base URL

$\bullet$ Note the location of the drivers



DataBase: Query [78]





\begin{picture}(510,285)(5,525)\thicklines
\put(415,685){\framebox (100,40){}...
...0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm 1: forName(driverName)}}}
\end{picture}




$\bullet$ Supplier calls execute() to loadSupplier() from DB, or storeSupplier() to DB

$\bullet$ First 5 lines of JDBC

$\bullet$ Static call to class loader makes sure the drivers are loaded

$\bullet$ Static call to DriverManager goes across network and validates password

$\bullet$ Connection provides an environment to make a query

$\bullet$ Execute an SQL query, either select or update/insert/delete

$\bullet$ Return the ResultSet of the data that matches the query (select)

$\bullet$ In either a DataBase main, or JUnit harness, test the DataBase stand-alone:

  DataBase db = new DataBase("SuppDB","4311","4311");  // 5 lines of JDBC
  ResultSet rs = db.execute("select * from S");
    try {
      while (rs.next())                                // 6th line of JDBC
        System.out.println(rs.getString("S_NO"));      // 7th line of JDBC
    } catch (SQLException e) {
        System.out.println(e.getMessage());
      }



Obsmain Program: Supplier/ObsFrame Construction [79]


\begin{picture}(590,229)(20,580)\thicklines
\put( 20,660){\framebox (110,120)...
...(465,720){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm ...}}}
\end{picture}

$\bullet$ Main() should create $n$ frames observing ``s1'', likewise for ``s2''



Obsmain Program: Supplier Construction [80]





\begin{picture}(585,425)(5,380)\thicklines
\put(420,640){\framebox (100,40){}...
...,780){\makebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm Integer}}}
\end{picture}




$\bullet$ java Obsmain 3 : means to create 3 frames observing s1, likewise for s2

$\bullet$ In one loop : create s1, create ObsFrame and give it s1; likewise for s2

$\bullet$ Supplier constructor stores number, creates db, calls loadSupplier() to load from DB



Supplier: Load Data [81]





\begin{picture}(485,189)(100,635)\thicklines
\put(100,740){\framebox (100,40)...
...(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm \underline{:Supplier}}}}
\end{picture}




$\bullet$ Supplier calls loadSupplier() at construction to load from DB

$\bullet$ loadSupplier() executes a query to locate particular S_NO

$\bullet$ Note that query needs to have embedded quotes around the number

"select * from S where S_NO='" + number + "'"

$\bullet$ next() increments the cursor forward to the one selected row (6th line of JDBC)

$\bullet$ getString() loads the values of the fields (7th line of JDBC)



Supplier: Store Data [82]





\begin{picture}(290,134)(10,680)\thicklines
\put(140,740){\framebox (100,40){...
...box(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm 3: status:=aStatus}}}
\end{picture}



$\bullet$ ObsFrame calls updateSupplier() when the button is pushed

$\bullet$ Supplier's mutator method sets the fields

$\bullet$ Call Observable's setChanged() to set the ``dirty'' bit

$\bullet$ Call Observable's notifyObservers to iterate through Observers (only if bit is set)

$\bullet$ Call storeSupplier() to update fields in database





\begin{picture}(440,200)(40,580)\thicklines
\put(100,740){\framebox (100,40){...
...ebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm '', CITY=''+city+}}}
\end{picture}



$\bullet$ Supplier calls storeSupplier() whenever the Supplier mutates

$\bullet$ Update the fields in the database

$\bullet$ name, city, number require quotes

$\bullet$ Use embedded single quotes



ObsFrame: Refresh [83]


\begin{picture}(400,224)(140,620)\thicklines
\put(440,620){\framebox (100,40)...
...ebox(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm displaySupplier()}}}
\end{picture}



$\bullet$ ObsFrame calls displaySupplier() at construction and when notified (update) by Observable

$\bullet$ ObsFrame's displaySupplier() accesses each Supplier field, and displays



ObsFrame: Events [84]




\begin{picture}(535,265)(5,520)\thicklines
\put(140,740){\framebox (100,40){}...
...raisebox{0pt}[0pt][0pt]{\twlrm do the same for name,city,status}}}
\end{picture}



$\bullet$ AWT calls actionPerformed() when the button (or menu) is selected

$\bullet$ ObsFrame ``is a'' ActionListener and must have actionPerformed()

$\bullet$ Convert the event into a String argument

$\bullet$ If "Exit", shutdown the System

$\bullet$ Sample each TextField and hand-over to the Supplier's mutator

$\bullet$ Note that a,b,c,d are just placeholders and do NOT need to be used



ObsFrame: GUI [85]





\begin{picture}(555,345)(5,440)\thicklines
\put(460,740){\framebox (100,40){}...
...,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm need menu with ''Exit''}}}
\end{picture}



$\bullet$ Register this ObsFrame with the Supplier (don't forget to save the Supplier)

$\bullet$ Make a FlowLayout

$\bullet$ Add Labels

$\bullet$ Add TextFields

$\bullet$ Create a SUBMIT or UPDATE button

$\bullet$ ObsFrame listens for a push on a button

$\bullet$ Make a Menu

$\bullet$ Call displaySupplier() to load initial data



Snapshot Pattern: Serialization [86]



$\bullet$ Use Java's serialization mechanism to perform Snapshot Pattern for persistence

$\bullet$ Alternative to object persistence using SQL

$\bullet$ loadSupplier(), storeSupplier() use serialization instead of SQL database

$\bullet$ Each Supplier record is store in it's own file (e.g. ``S1.dat'')

$\bullet$ Class must implement the Serializable interface, but requires no extra methods

$\bullet$ The class is ``marked'' as a candidate for serialization

$\bullet$ Supplier attributes moved to Supp class

$\bullet$ DataBase handle replaced by Supp handle

$\bullet$ Memory to disk: (new ObjectOutputStream(new FileOutputStream(filename))).writeObject(obj);

$\bullet$ Disk to memory: obj = (new ObjectInputStream(new FileInputStream(filename))).readObject();

$\bullet$ File Streams ``know'' how to read/write bytes of a file

$\bullet$ Object Streams ``know'' the attributes/methods of the class, and use the File Streams

$\bullet$ ObjectOutputStream completely serializes (flattens) the Supplier object

$\bullet$ Data file contains enough information to completely reconstruct the object in memory



Snapshot Pattern: Serialization [87]


\begin{picture}(530,519)(35,320)\thicklines
\put( 35,695){\framebox (65,45){}...
...x(0,0)[lb]{\raisebox{0pt}[0pt][0pt]{\twlrm Supp(aNumber:String)}}}
\end{picture}


next up previous contents
Next: Remote(RMI)/Persistent Objects Up: Case Study Previous: Case Study   Contents
Ted Billard 2006-09-26