MVC

Video created from my 401 (http://www.cs.unc.edu/~dewan/comp401/current/) Fall 13 lecture. See http://www.cs.unc.edu/~dewan/comp401/current/Lectures/MVC.pptx for the original PPT and http://www.cs.unc.edu/~dewan/comp401/current/Lectures/MVC.pdf for the pdf.

1.0x

MVC

Created 2 years ago

Duration 2:20:09
lesson view count 13
Video created from my 401 (http://www.cs.unc.edu/~dewan/comp401/current/) Fall 13 lecture. See http://www.cs.unc.edu/~dewan/comp401/current/Lectures/MVC.pptx for the original PPT and http://www.cs.unc.edu/~dewan/comp401/current/Lectures/MVC.pdf for the pdf.
Select the file type you wish to download
Slide Content
  1. Comp 401Model-View-Controller(MVC)

    Slide 1 - Comp 401Model-View-Controller(MVC)

    • Instructor: Prasun Dewan
  2. Prerequisites

    Slide 2 - Prerequisites

    • Interfaces
    • Main Console Input
    • Inheritance
  3. General Problem

    Slide 3 - General Problem

    • How to break up our program into multiple classes?
  4. Separation of Concerns

    Slide 4 - Separation of Concerns

    • History Semantics
    • History Display 1
    • History Semantics
    • History Display 2
    • Can change display without changing other aspects of history
    • Display and semantics should go in different classes
  5. Separation of Concerns

    Slide 5 - Separation of Concerns

    • A
    • B
    • A
    • B’
    • if a part A of a class can be changed without changing some other part B of the class, then refactor and put A and B in different classes
  6. Patterns

    Slide 6 - Patterns

    • Recurring theme
    • Bean, Vector pattern
    • Conventions for readability
    • Loop patterns
    • Event-controlled
    • Counter controlled
    • Design patterns
    • Helps identify the kind of classes our program should have
  7. Design Pattern

    Slide 7 - Design Pattern

    • Reusable program decomposition pattern
    • Not specific class or interface, infinite family of classes/interfaces implement this pattern.
    • Usually involves multiple objects
    • Language-independent
    • Include architecture and frameworks
    • Inspired by Architectural Pattern (Chrstopher Plummer)
  8.  Screened-in porch

    Slide 8 - Screened-in porch

    • 2nd story porch
    • supported by
    • 1st floor porch
    • columns
    • Flat (not bay) window
    • DIFFERENT
    • No outside stairs to
    • 2nd story
    • Wide plank siding
    • SIMILAR
  9. MVC Motivation

    Slide 9 - MVC Motivation

    • History Semantics
    • History Display 1
    • History Semantics
    • History Display 2
    • Can change display without changing other aspects of history
    • Display and semantics should go in different classes
  10. MVC Motivation

    Slide 10 - MVC Motivation

    • Object Semantics/Service
    • Object User Interface
    • Object Semantics/service
    • Object User Interface
  11. Questions

    Slide 11 - Questions

    • How to reuse code among different interactive applications offering the same service?
    • How to simultaneously create multiple user interfaces for same service?
    • Normal vs. Slide sorter
    • Shortcuts vs. menus vs. buttons
  12. Questions

    Slide 12 - Questions

    • How to simultaneously create multiple user interfaces for same service on different computers?
    • Facebook, email
  13. Questions

    Slide 13 - Questions

    • How to simultaneously create distributed user interfaces
    • multiple complete user interfaces for different users on different computers
    • Single user-interface on large computer controlled by multiple mobile devices
  14. Example: Counter

    Slide 14 - Example: Counter

    • Can add arbitrary positive/negative value to an integer
    • Different user interfaces
  15. Console Input and Output

    Slide 15 - Console Input and Output

  16. Console Input and JOption Output

    Slide 16 - Console Input and JOption Output

  17. Console Input,Output and JOption Output

    Slide 17 - Console Input,Output and JOption Output

  18. Monolithic Console UI IMPLEMENTATION

    Slide 18 - Monolithic Console UI IMPLEMENTATION

    • public class MonolithicConsoleUI {
    • public static void main(String[] args) {
    • int counter = 0;
    • while (true) {
    • System.out.println("Counter: " + counter);
    • int nextInput = Console.readInt();
    • if (nextInput == 0) break;
    • counter += nextInput;
    • }
    • }
    • }
  19. Monolithic Console UI IMPLEMENTATION

    Slide 19 - Monolithic Console UI IMPLEMENTATION

    • public class MonolithicConsoleUI {
    • public static void main(String[] args) {
    • int counter = 0;
    • while (true) {
    • System.out.println("Counter: " + counter);
    • int nextInput = Console.readInt();
    • if (nextInput == 0) break;
    • counter += nextInput;
    • }
    • }
    • }
  20. import javax.swing.JOptionPane;

    Slide 20 - import javax.swing.JOptionPane;

    • public class ConsoleUI {
    • public static void main(String[] args) {
    • int counter = 0;
    • while (true) {
    • JOptionPane.showMessageDialog(
    • null, “Counter: ” + counter);
    • int nextInput = Console.readInt();
    • if (nextInput == 0) break;
    • counter += nextInput;
    • }
    • }
    • }
    • Monolithic Mixed UI Implementation
    • Code duplication
  21. import javax.swing.JOptionPane;

    Slide 21 - import javax.swing.JOptionPane;

    • public class ConsoleUI {
    • public static void main(String[] args) {
    • int counter = 0;
    • while (true) {
    • JOptionPane.showMessageDialog(
    • null, “Counter: ” + counter);
    • int nextInput = Console.readInt();
    • if (nextInput == 0) break;
    • counter += nextInput;
    • }
    • }
    • }
    • Multiple UIs?
    • Cannot use both UIs simultaneously to update same counter
  22. Counter Model

    Slide 22 - Counter Model

    • public class ACounter implements Counter {
    • int counter = 0;
    • public void add (int amount) {
    • counter += amount;
    • }
    • public int getValue() {
    • return counter;
    • }
    • }
    • No input/output
  23. Model/Interactor(Editor) Separation

    Slide 23 - Model/Interactor(Editor) Separation

    • Counter
    • AConsoleUI
    • AMultipleUI
    • AMixedUI
    • Model
    • Model has no UI code and only semantics!
    • Interactor
    • Interactor
    • Interactor or Editor
    • public static void main (String args[]) {
    • (new AConsoleUI()).edit (new ACounter());
    • }
  24. Model?

    Slide 24 - Model?

  25. Counter Model

    Slide 25 - Counter Model

    • public class ACounter implements Counter {
    • int counter = 0;
    • public void add (int amount) {
    • counter += amount;
    • }
    • public int getValue() {
    • return counter;
    • }
    • }
    • No input/output
  26. Monolithic Console UI IMPLEMENTATION

    Slide 26 - Monolithic Console UI IMPLEMENTATION

    • public class ConsoleUI {
    • public static void main(String[] args) {
    • int counter = 0;
    • while (true) {
    • System.out.println("Counter: " + counter);
    • int nextInput = Console.readInt();
    • if (nextInput == 0) break;
    • counter += nextInput;
    • }
    • }
    • }
  27. Console Interactor

    Slide 27 - Console Interactor

    • public class AConsoleUIInteractor implements CounterInteractor {
    • public void edit (Counter counter) {
    • while (true) {
    • System.out.println("Counter: " + counter.getValue());
    • int nextInput = Console.readInt();
    • if (nextInput == 0) return;
    • counter.add(nextInput);
    • }
    • }
    • }
  28. Mixed Interactor

    Slide 28 - Mixed Interactor

    • public class AMixedUIInteractor implements CounterInteractor {
    • public void edit (Counter counter) {
    • while (true) {
    • JOptionPane.showMessageDialog(null,
    • "Counter: " + counter.getValue());
    • int nextInput = Console.readInt();
    • if (nextInput == 0) break;
    • counter.add(nextInput);
    • }
    • }
    • }
    • Shared Model Code
    • Input
    • Output
    • I/O Code is Duplicated
    • UI Implementation is now monolithic
  29. Multiple UI Interactor

    Slide 29 - Multiple UI Interactor

    • public class AMultipleUI implements CounterInteractor {
    • public void edit (Counter counter) {
    • while (true) {
    • System.out.println("Counter: " + counter.getValue());
    • JOptionPane.showMessageDialog(null,
    • "Counter: " + counter.getValue());
    • int nextInput = Console.readInt();
    • if (nextInput == 0) break;
    • counter.add(nextInput);
    • }
    • }
    • }
    • Shared Model Code
    • Input
    • Output
    • I/O Code is Duplicated
    • UI Implementation is now monolithic
  30. Drawbacks of Monolithic UI

    Slide 30 - Drawbacks of Monolithic UI

    • Counter
    • AConsoleUI
    • AMultipleUI
    • AMixedUI
    • Duplicated Input Code
    • Duplicated Output Code
  31. Model/Interactor Pattern

    Slide 31 - Model/Interactor Pattern

    • Model
    • Interactor
    • UI Code
    • Computation Code
    • Arbitrary UI unaware methods
  32. MVC Pattern

    Slide 32 - MVC Pattern

    • View can be on computer with big screen and controller on smart phone
    • Read Methods
    • Write Methods
    • Model
    • View
    • Controller
    • Performs Input
    • Performs Output
  33. getValue()

    Slide 33 - getValue()

    • add()
    • MVC Pattern in Counter
    • Performs Input
    • Performs Output
    • Model
    • View
    • Controller
  34. getValue()

    Slide 34 - getValue()

    • add()
    • Changing to Console View
    • Performs Input
    • Performs Output
    • Model
    • View
    • Controller
  35. getValue()

    Slide 35 - getValue()

    • add()
    • Multiple Views
    • Performs Input
    • Performs Output
    • View
    • Model
    • View
    • Controller
  36. Multiple Views and Controllers

    Slide 36 - Multiple Views and Controllers

    • Menus, buttons, shortcuts can be handled by different controllers (in same or different program)
    • Model
    • Controller 1
    • Controller 2
    • Controller 3
    • Controller 4
    • View 1
    • View 2
    • View 3
    • View 4
  37. Syncing Controllers & View

    Slide 37 - Syncing Controllers & View

    • Model
    • Controller 1
    • Controller 2
    • Controller 3
    • Controller 4
    • View 1
    • View 2
    • View 3
    • View 4
    • In Http-based “MVC” a single view and controller exist in the browser and the model in the server. A Model cannot initiate actions in the browser so the controller directly communicates with the view
  38. Observer Pattern

    Slide 38 - Observer Pattern

    • Changed model notifies views
    • Observers
    • Observable
    • Model
    • View 1
    • View 2
    • View 3
    • View 4
  39. Multiple  Observers/Observables

    Slide 39 - Multiple Observers/Observables

    • Observable 1
    • Observer 1
    • Observer 2
    • Observer 3
    • Observer N
    • Observable 2
    • A single battle simulation view observing
    • Multiple planes
    • Multiple tanks
    • How does observable know about its observers?
    • Observer registered with observable
  40. Notification Scheme

    Slide 40 - Notification Scheme

    • Each observer is registered with observable
    • Each write method in observable calls a notification method in each observer
    • Notification method in observer reads model
    • Each student is registered with professor’s listserv
    • When web page is updated mail sent to students
    • Student reads web page if mailed information is not sufficient
    • Observable 1
    • Observer 1
    • Observer 2
    • Observer 3
    • Observer N
    • Observable 2
  41. MVC Pattern (Review)

    Slide 41 - MVC Pattern (Review)

    • View can be on computer with big screen and controller on smart phone
    • Read Methods
    • Write Methods
    • Model
    • View
    • Controller
    • Performs Input
    • Performs Output
  42. getValue()

    Slide 42 - getValue()

    • add()
    • MVC Pattern in Counter (Review)
    • Performs Input
    • Performs Output
    • Model
    • View
    • Controller
  43. Observer Pattern

    Slide 43 - Observer Pattern

    • Controller 1
    • Controller 2
    • Controller 3
    • Controller 4
    • Changed model notifies views
    • Observers
    • Observable
    • Model
    • View 1
    • View 2
    • View 3
    • View 4
  44. Notification Scheme (Review)

    Slide 44 - Notification Scheme (Review)

    • Each observer is registered with observable
    • Each write method in observable calls a notification method in each observer
    • Notification method in observer reads model
    • Each student is registered with professor’s listserv
    • When web page is updated mail sent to students
    • Student reads web page if mailed information is not sufficient
    • Observable 1
    • Observer 1
    • Observer 2
    • Observer 3
    • Observer N
    • Observable 2
  45. General Notification Scheme

    Slide 45 - General Notification Scheme

    • Observers may have multiple observables with common notification method
    • Notification method parameter indicates which observable
    • Observable 1
    • Observer 1
    • Observer 2
    • Observer 3
    • Observer N
    • Observable 2
  46. Notifications in MVC Pattern

    Slide 46 - Notifications in MVC Pattern

    • Read Methods
    • Write Methods
    • Model
    • View
    • Controller
    • Performs Input
    • Performs Output
    • Notification Method
    • Observer Registration Method
  47. Implementation dependent issues

    Slide 47 - Implementation dependent issues

    • How does controller know about model?
    • Model connection method invoked on it
    • By model or some other program
    • Main
    • Who registers observer registered with observable?
    • It registers itself if it knows about observable
    • Model registers it if it knows about observer
    • Some other code registers it
    • Main
  48. getValue()

    Slide 48 - getValue()

    • Complete MVC
    • Model
    • View
    • add()
    • Controller
    • Performs Input
    • Performs Output
    • Notification Method
    • Model Connection Method
    • Observer Registration Method
  49. Observable and Observer

    Slide 49 - Observable and Observer

    • Each observer is registered with observable
    • Each write method in observable calls a notification method in each observer
    • Notification method in observer reads model
  50. Counter Observable and Observer

    Slide 50 - Counter Observable and Observer

    • public interface ObservableCounter {
    • public void add (int amount) ;
    • public int getValue() ;
    • public void addObserver(CounterObserver observer);
    • public void removeObserver(CounterObserver observer);
    • }
    • public interface CounterObserver {
    • public void update(ObservableCounter counter);
    • }
    • Console View, JOption View
    • Called whenever model is updated
    • Updated model
  51. Counter Model

    Slide 51 - Counter Model

    • public class AnObservableCounter implements ObservableCounter {
    • int counter = 0;
    • ObserverList observers = new AnObserverList();
    • public void add (int amount) {
    • counter += amount;
    • notifyAllObservers();
    • }
    • public int getValue() {
    • return counter;
    • }
    • public void addObserver(CounterObserver observer) {
    • observers.addElement(observer);
    • observer.update(this);
    • }
    • public void removeObserver(CounterObserver observer) {
    • observers.removeElement(observer);
    • }
    • void notifyAllObservers() {
    • for (int observerNum = 0; observerNum < observers.size();
    • observerNum++)
    • observers.elementAt(observerNum).update(this);
    • }
    • }
    • Give this observable initial value
    • Each write method notifies all!
  52. Console View

    Slide 52 - Console View

    • public class ACounterConsoleView implements CounterObserver {
    • public void update(ObservableCounter counter) {
    • System.out.println("Counter: " + counter.getValue());
    • }
    • }
  53. JOption View

    Slide 53 - JOption View

    • import javax.swing.JOptionPane;
    • public class ACounterJOptionView implements CounterObserver {
    • public void update(ObservableCounter counter) {
    • JOptionPane.showMessageDialog(
    • null, "Counter: " + counter.getValue());
    • }
    • }
  54. Console Controller Interface

    Slide 54 - Console Controller Interface

    • public interface CounterController {
    • public void setModel(ObservableCounter theCounter);
    • public void processInput();
    • }
  55. Console Controller

    Slide 55 - Console Controller

    • public class ACounterController implements CounterController {
    • ObservableCounter counter;
    • public void setModel(ObservableCounter theCounter) {
    • counter = theCounter;
    • }
    • public void processInput() {
    • while (true) {
    • int nextInput = Console.readInt();
    • if (nextInput == 0) break;
    • counter.add(nextInput);
    • }
    • }
    • }
  56. Console Main

    Slide 56 - Console Main

    • public static void main (String args[]) {
    • ObservableCounter model = new AnObservableCounter();
    • model.addObserver(new ACounterConsoleView());
    • CounterController controller = new ACounterController();
    • controller.setModel(model);
    • controller.processInput();
    • }
  57. Console and JOption Main

    Slide 57 - Console and JOption Main

    • public static void main (String args[]) {
    • ObservableCounter model = new AnObservableCounter();
    • model.addObserver (new ACounterJOptionView());
    • CounterController controller = new ACounterController();
    • controller.setModel(model);
    • controller.processInput();
    • }
    • Shared input code
  58. Mixed UI Main

    Slide 58 - Mixed UI Main

    • public static void main (String args[]) {
    • ObservableCounter model = new AnObservableCounter();
    • model.addObserver(new ACounterJOptionView());
    • model.addObserver (new ACounterConsoleView());
    • CounterController controller = new ACounterController();
    • controller.setModel(model);
    • controller.processInput();
    • }
  59. Efficiency

    Slide 59 - Efficiency

    • What if observer is in USA and observable in China?
    • Update must make a “long distance” call to read method (getValue()) to update counter state
    • public interface CounterObserver {
    • public void update(ObservableCounter counter);
    • }
    • public class ACounterConsoleView implements CounterObserver {
    • public void update(ObservableCounter counter) {
    • System.out.println("Counter: " + counter.getValue());
    • }
    • }
  60. Notification with Change Description

    Slide 60 - Notification with Change Description

    • public interface CounterObserver {
    • public void update(ObservableCounter counter, int newCounterVal);
    • }
    • No need to call read method after notification
    • public class ACounterConsoleView implements CounterObserver {
    • public void update(ObservableCounter counter, int newCounterVal) {
    • System.out.println("Counter: " + newCounterVal));
    • }
    • }
  61. ObjectEditor Update?

    Slide 61 - ObjectEditor Update?

    • public interface CounterObserver {
    • public void update(ObservableCounter counter, int newCounterVal);
    • }
    • Can ObjectEditor become a view of Counter so no need to call refresh?
    • ObjectEditor does not know about CounterObserver and cannot implement it.
  62.  java.util.Observer and Observable

    Slide 62 - java.util.Observer and Observable

    • public interface java.util.Observer {
    • public void update(Observable o, Object arg);
    • }
    • “Standard” observer interface talking arbitrary change Object argument
    • public class java.util.Observable {
    • public void addObserver(Observer o) { … };
    • public void notifyObservers() { … };
    • }
    • Model must be subclass of Observable
  63. Extra

    Slide 63 - Extra

  64. Circularity

    Slide 64 - Circularity

    • public interface ObservableCounter {
    • public void add (int amount) ;
    • public int getValue() ;
    • public void addObserver(CounterObserver observer);
    • public void removeObserver(CounterObserver observer);
    • }
    • public interface CounterObserver {
    • public void update(ObservableCounter counter);
    • }
    • Cannot compile ObservableCounter without CounterObserver and vice versa
  65. Breaking Circularity: Multiple Stages

    Slide 65 - Breaking Circularity: Multiple Stages

    • public interface ObservableCounter {
    • public void add (int amount) ;
    • public int getValue() ;
    • }
    • public interface CounterObserver {
    • public void update(ObservableCounter counter);
    • }
    • CounterObserver references compiled ObservableCounter
  66. Circularity

    Slide 66 - Circularity

    • public interface ObservableCounter {
    • public void add (int amount) ;
    • public int getValue() ;
    • public void addObserver(CounterObserver observer);
    • public void removeObserver(CounterObserver observer);
    • }
    • public interface CounterObserver {
    • public void update(ObservableCounter counter);
    • }
    • Recompiled observable references compiled CounterObserver
  67. Circularity and Breaking it

    Slide 67 - Circularity and Breaking it

    • Circularity
    • Two types reference each other
    • Neither can be compiled without the other
    • General approach to breaking it
    • Create both types as empty and compile them so they are known to Java
    • Next add references to each other
  68. Counter Model

    Slide 68 - Counter Model

    • public class AnObservableCounter implements ObservableCounter {
    • int counter = 0;
    • ObserverList observers = new AnObserverList();
    • public void add (int amount) {
    • counter += amount;
    • notifyAllObservers();
    • }
    • public int getValue() {
    • return counter;
    • }
    • public void addObserver(CounterObserver observer) {
    • observers.addElement(observer);
    • observer.update(this);
    • }
    • public void removeObserver(CounterObserver observer) {
    • observers.removeElement(observer);
    • }
    • void notifyAllObservers() {
    • for (int observerNum = 0; observerNum < observers.size();
    • observerNum++)
    • observers.elementAt(observerNum).update(this);
    • }
    • }
    • Give this observable initial value
    • Each write method notifies all!
  69. Console View

    Slide 69 - Console View

    • public class ACounterConsoleView implements CounterObserver {
    • public void update(ObservableCounter counter) {
    • System.out.println("Counter: " + counter.getValue());
    • }
    • }
  70. JOption View

    Slide 70 - JOption View

    • import javax.swing.JOptionPane;
    • public class ACounterJOptionView implements CounterObserver {
    • public void update(ObservableCounter counter) {
    • JOptionPane.showMessageDialog(
    • null, "Counter: " + counter.getValue());
    • }
    • }
  71. Console Controller Interface

    Slide 71 - Console Controller Interface

    • public interface CounterController {
    • public void setModel(ObservableCounter theCounter);
    • public void processInput();
    • }
  72. Console Controller

    Slide 72 - Console Controller

    • public class ACounterController implements CounterController {
    • ObservableCounter counter;
    • public void setModel(ObservableCounter theCounter) {
    • counter = theCounter;
    • }
    • public void processInput() {
    • while (true) {
    • int nextInput = Console.readInt();
    • if (nextInput == 0) break;
    • counter.add(nextInput);
    • }
    • }
    • }
  73. Console Main

    Slide 73 - Console Main

    • public static void main (String args[]) {
    • ObservableCounter model = new AnObservableCounter();
    • model.addObserver(new ACounterConsoleView());
    • CounterController controller = new ACounterController();
    • controller.setModel(model);
    • controller.processInput();
    • }
  74. Console and JOption Main

    Slide 74 - Console and JOption Main

    • public static void main (String args[]) {
    • ObservableCounter model = new AnObservableCounter();
    • model.addObserver (new ACounterJOptionView());
    • CounterController controller = new ACounterController();
    • controller.setModel(model);
    • controller.processInput();
    • }
    • Shared input code
  75. Mixed UI Main

    Slide 75 - Mixed UI Main

    • public static void main (String args[]) {
    • ObservableCounter model = new AnObservableCounter();
    • model.addObserver(new ACounterJOptionView());
    • model.addObserver (new ACounterConsoleView());
    • CounterController controller = new ACounterController();
    • controller.setModel(model);
    • controller.processInput();
    • }
  76. Observers that are not views

    Slide 76 - Observers that are not views

    • Spreadsheet cell
    • observes cells on which it depends
    • Monitoring of appliance usage
    • Each time I do setChannel() on TV event logged
    • Eclipse quiz/activity plug-in
    • Observers Eclipse events
    • Any big brother app!
    • Counter observer?
  77. Observers that are not views

    Slide 77 - Observers that are not views

    • Spreadsheet cell
    • observes cells on which it depends
    • Monitoring of appliance usage
    • Each time I do setChannel() on TV event logged
    • Eclipse quiz/activity plug-in
    • Observers Eclipse events
    • Any big brother app!
    • Counter observer?
  78. Rocket Observer

    Slide 78 - Rocket Observer

    • public class ARocketLaunchingCounterObserver
    • implements CounterObserver {
    • public void update(ObservableCounter counter) {
    • if (counter.getValue() == 0)
    • launch();
    • }
    • private void launch() {
    • System.out.println("LIFT OFF!!!");
    • }
    • }
  79. Slide 79

    • Instances created and composed
    • AnObservable
    • Counter
    • ARocketLaunchingCounterObserver
    • Controller
    • ACounterConsoleView
    • ARocketLauncher
    • Console View added before rocket launching observer
  80. Rocket Launching Main

    Slide 80 - Rocket Launching Main

    • public static void main (String args[]) {
    • ObservableCounter model = new AnObservableCounter();
    • model.addObserver (new ACounterConsoleView());
    • model.addObserver(new ARocketLaunchingCounterObserver());
    • CounterController controller = new ACounterController();
    • controller.setModel(model);
    • controller.processInput();
    • }
  81. Basic Notification

    Slide 81 - Basic Notification

    • public interface CounterObserver {
    • public void update(ObservableCounter counter);
    • }
    • Called when observer is updated
    • Updated Observable
  82. Implicit Observer

    Slide 82 - Implicit Observer

    • public interface CounterObserver {
    • public void setObservable(ObservableCounter counter);
    • public void update();
    • }
    • Updated Observable
    • Assuming observer has only one observable
  83. Distribution Issues

    Slide 83 - Distribution Issues

    • What if observer is in USA and observable in China?
    • Update must make a “long distance” call to read method (getValue()) to update counter state
    • public interface CounterObserver {
    • public void update(ObservableCounter counter);
    • }
  84. Notification with Change Description

    Slide 84 - Notification with Change Description

    • package models;
    • public interface CounterObserver {
    • public void update(ObservableCounter counter, int newCounterVal);
    • }
    • No need to call read method after notification
  85. Java java.util.Observer

    Slide 85 - Java java.util.Observer

    • public interface java.util.Observer {
    • public void update(Observable o, Object arg);
    • }
    • “Standard” observer interface talking arbitrary change Object argument
  86. Notification with Changed Value

    Slide 86 - Notification with Changed Value

    • public interface CounterObserver {
    • public void update(ObservableCounter counter, int newCounterVal);
    • }
    • New value of observable attribute
  87. Notification with Change

    Slide 87 - Notification with Change

    • public interface CounterObserver {
    • public void update(ObservableCounter counter, int counterIncrement);
    • }
    • Difference between new and old value of observable attribute
    • Observer may display change to user
    • Observer interested in change does not need to keep old value to determine change
    • Observer interested in absolute value must keep old value
  88. Notification with New and Old Value

    Slide 88 - Notification with New and Old Value

    • public interface CounterObserver {
    • public void update (ObservableCounter counter,
    • int oldCounterValue, int newCounterValue);
    • }
    • Old and new value of observable attribute
    • Observer interested in change does not need to keep old value to determine change
    • Observer interested in absolute value need not keep old value
    • Makes observer harder to code
  89. Notification with Single Event Object

    Slide 89 - Notification with Single Event Object

    • public interface CounterObserver {
    • public void update(
    • CounterChangeEvent event);
    • }
    • public interface CounterChangeEvent {
    • ObservableCounter getCounter();
    • int getOldCounterValue();
    • int getNewCounterValue();
    • }
    • Easy to pass single object to different methods handling event
    • Can make event info very elaborate
    • Time when event occurred
    • Unique ID for event
    • ….
    • Callee does not have to declare parameters for event information fields not of interest
    • Caller does not have to fill every value – can put null for object values such as counter and illegal values for primitives
  90. Java ActionEvent

    Slide 90 - Java ActionEvent

    • import java.awt.Event;
    • public interface java.awt.ActionListener {
    • public void actionPerformed(ActionEvent e);
    • }
    • When you edit text and hit return this event sent by JTextField, TextField widget to its listeners such as ObjectEditor
    • When you press a button, this event sent by Button/Jbutton to its lsisteners such as ObjectEditor
  91. Observing Multiple Properties

    Slide 91 - Observing Multiple Properties

    • public interface BMISpreadsheet {
    • public double getHeight();
    • public void setHeight(int newVal);
    • public double getWeight() ;
    • public void setWeight(int newWeight) ;
    • public double getBMI();
    • }
    • Observer Inteface?
  92. Single Coarse-Grained Update

    Slide 92 - Single Coarse-Grained Update

    • public interface BMISpreadsheet {
    • public double getHeight();
    • public void setHeight(int newVal);
    • public double getWeight() ;
    • public void setWeight(int newWeight) ;
    • public double getBMI();
    • ….
    • }
    • public interface BMIObserver {
    • public void update(
    • BMISpreadsheet bmiSpreadsheet);
    • }
    • Coarse grained updated
    • Each setter sends the whole object
    • Observer must determine which property changed
  93. Multiple fine-grained updates

    Slide 93 - Multiple fine-grained updates

    • public interface BMIObserver {
    • public void updateHeight (
    • BMISpreadsheet bmi, int oldHeight, int newHeight);
    • public void updateWeight(
    • BMISpreadsheet bmi, int oldWeight, int newWeight);
    • public void updateBMI(
    • BMISpreadsheet bmi, double oldBMI, double newBMI);
    • }
    • public interface BMISpreadsheet {
    • public double getHeight();
    • public void setHeight(int newVal);
    • public double getWeight() ;
    • public void setWeight(int newWeight) ;
    • public double getBMI();
    • ...
    • }
  94. Single fine-grained update method

    Slide 94 - Single fine-grained update method

    • public interface BMIObserver {
    • public void update(
    • BMISpreadsheet bmi, String propertyName, Object oldValue, Object newValue);
    • }
    • New methods not needed as new properties added
    • Different setters calls the same update method with different types of values.
    • Can be used for arbitrary property values
    • Can make mistakes and must process property name to determine wat changed
    • “Wght”
    • “One”
    • public interface BMISpreadsheet {
    • public double getHeight();
    • public void setHeight(int newVal);
    • public double getWeight() ;
    • public void setWeight(int newWeight) ;
    • public double getBMI();
    • }
  95. Custom Single fine-grained update method

    Slide 95 - Custom Single fine-grained update method

    • public void setHeight (int newVal) {
    • int oldVal = height;
    • height = newVal;
    • notifyAllObservers(this, “height”, oldVal, newVal);
    • }
    • public void notifyAllObservers(BMISpreadsheet source, String propertyName, Object oldValue, Object newValue) {
    • for (int index = 0; index < observers.size(); index++) {
    • observers.elementAt(index).update(source, propertyName, oldValue, newValue);
    • }
    • BMIObserver
    • Can make mistake