Multiple Observer Frames watch the Observable Supplier
Each Frame registers with the Supplier using a call to addObserver(this)
Supplier does addElement(observer) to the Vector in Observable
User presses SUBMIT on a Frame, which mutates() the Supplier
Supplier modifies the disk using SQL or Java's Serializable interface
Supplier calls inherited notifyObservers()
notifyObservers() iterates through Vector, casts, calls update() on Frame
Each Frame has an update(), which calls the Supplier's accessor methods
Frame refreshes the screen
Observable/Persistent Classes: Responsibilities [75]
The following diagrams provide detail about the Class Responsibilities:
Observable: maintain Vector of registered Observers, notifyObservers() upon mutation
Observer: interface to enforce ObsFrame to have update() method
Obsmain: create 2 Suppliers, and
ObsFrames per to watch
DataBase: perform first 5 (out of 7) steps of JDBC to query database
ObsFrame: register as Observer, display 4 fields, button causes mutate(), update() causes displaySupplier()
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]
DataBase: Construction [77]
DataBase is constructed by the Supplier when it is constructed
Constructor for DataBase initializes private variables
Base URL indicates where the server is located and the port it uses
URL needs to have the database name appended to the base URL
Note the location of the drivers
DataBase: Query [78]
Supplier calls execute() to loadSupplier() from DB, or storeSupplier() to DB
First 5 lines of JDBC
Static call to class loader makes sure the drivers are loaded
Static call to DriverManager goes across network and validates password
Connection provides an environment to make a query
Execute an SQL query, either select or update/insert/delete
Return the ResultSet of the data that matches the query (select)
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]
Main() should create
frames observing ``s1'', likewise for ``s2''
Obsmain Program: Supplier Construction [80]
java Obsmain 3 : means to create 3 frames observing s1, likewise for s2
In one loop : create s1, create ObsFrame and give it s1; likewise for s2
Supplier constructor stores number, creates db, calls loadSupplier() to load from DB
Supplier: Load Data [81]
Supplier calls loadSupplier() at construction to load from DB
loadSupplier() executes a query to locate particular S_NO
Note that query needs to have embedded quotes around the number
"select * from S where S_NO='" + number + "'"
next() increments the cursor forward to the one selected row (6th line of JDBC)
getString() loads the values of the fields (7th line of JDBC)
Supplier: Store Data [82]
ObsFrame calls updateSupplier() when the button is pushed
Supplier's mutator method sets the fields
Call Observable's setChanged() to set the ``dirty'' bit
Call Observable's notifyObservers to iterate through Observers (only if bit is set)
Call storeSupplier() to update fields in database
Supplier calls storeSupplier() whenever the Supplier mutates
Update the fields in the database
name, city, number require quotes
Use embedded single quotes
ObsFrame: Refresh [83]
ObsFrame calls displaySupplier() at construction and when notified (update) by Observable
ObsFrame's displaySupplier() accesses each Supplier field, and displays
ObsFrame: Events [84]
AWT calls actionPerformed() when the button (or menu) is selected
ObsFrame ``is a'' ActionListener and must have actionPerformed()
Convert the event into a String argument
If "Exit", shutdown the System
Sample each TextField and hand-over to the Supplier's mutator
Note that a,b,c,d are just placeholders and do NOT need to be used
ObsFrame: GUI [85]
Register this ObsFrame with the Supplier (don't forget to save the Supplier)
Make a FlowLayout
Add Labels
Add TextFields
Create a SUBMIT or UPDATE button
ObsFrame listens for a push on a button
Make a Menu
Call displaySupplier() to load initial data
Snapshot Pattern: Serialization [86]
Use Java's serialization mechanism to perform Snapshot Pattern for persistence
Alternative to object persistence using SQL
loadSupplier(), storeSupplier() use serialization instead of SQL database
Each Supplier record is store in it's own file (e.g. ``S1.dat'')
Class must implement the Serializable interface, but requires no extra methods
The class is ``marked'' as a candidate for serialization
Supplier attributes moved to Supp class
DataBase handle replaced by Supp handle
Memory to disk: (new ObjectOutputStream(new FileOutputStream(filename))).writeObject(obj);
Disk to memory: obj = (new ObjectInputStream(new FileInputStream(filename))).readObject();
File Streams ``know'' how to read/write bytes of a file
Object Streams ``know'' the attributes/methods of the class, and use the File Streams
ObjectOutputStream completely serializes (flattens) the Supplier object
Data file contains enough information to completely reconstruct the object in memory
Snapshot Pattern: Serialization [87]