Download presentation
Presentation is loading. Please wait.
1
Model View Controller Prasun Dewan Comp 114
2
Model View Controller Pattern Issue –How to create user-interface objects like object editor Model-View-Controller Pattern –Observer sub-pattern
3
User Interface Objects How to reuse code among different user interfaces? How to simultaneously create multiple user interfaces to same object? –Different views for same user. Slide sorter vs. Outline –How to create different view for different views sharing same object Distributed presentation
4
Example: Counter Can add arbitrary positive/negative value to it. Different UIs sharing component. Multiple UIs
5
Example: Counter package models; public class ACounter implements Counter { int counter = 0; public void add (int amount) { counter += amount; } public int getValue() { return counter; }
6
Console Input and Output
7
Console Input and JOption Output
8
Console Input,Output and JOption Output
9
Benefits of Object/UI Separation AConsoleUIMainAMixedUIMain AMultipleUIMain ACounter
10
Model/Interactor Pattern Interactor Model Arbitrary UI unaware methods Computation code UI Code
11
Monolithic Main for Console I/O public class ACounterWithConsoleControllerAndView { public static void main(String[] args) { Counter counter = new ACounter(); appendToConsole(counter.getValue()); processInput(counter); } static void appendToConsole(int counterValue) { System.out.println("Counter: " + counterValue); } public static void processInput(Counter counter) { while (true) { int nextInput = readInt(); if (nextInput == 0) return; counter.add(nextInput); appendToConsole (counter.getValue()); } //readInt()... }
12
Monolithic Main for Mixed I/O public class ACounterWithConsoleControllerAndJOptionView { public static void main(String[] args) { Counter counter = new ACounter(); displayMessage(counter.getValue()); processInput(counter); } static void displayMessage(int counterValue) { JOptionPane.showMessageDialog(null, "Counter: " + counterValue); } public static void processInput(Counter counter) { while (true) { int nextInput = readInt(); if (nextInput == 0) return; counter.add(nextInput); displayMessage (counter.getValue()); } //readInt()... }
13
Monolithic Main for Mixed I/O public class ACounterWithConsoleControllerAndViewAndJOptionView { public static void main(String[] args) { Counter counter = new ACounter(); displayOutput(counter.getValue()); processInput(counter); } static void appendToConsole(int counterValue) { System.out.println("Counter: " + counterValue); } static void displayMessage(int counterValue) { JOptionPane.showMessageDialog(null, "Counter: " + counterValue); } static void displayOutput(int counterValue) { appendToConsole(counterValue); displayMessage(counterValue); } public static void processInput(Counter counter) { while (true) { int nextInput = readInt(); if (nextInput == 0) return; counter.add(nextInput); displayOutput(counter.getValue()); } //readInt()... }
14
Drawbacks of Monolithic UI AConsoleUIMainAMixedUIMain AMultipleUIMain ACounter Duplicated input code Duplicated output code
15
Model/Interactor Pattern Interactor Model Arbitrary UI unaware methods Computation code UI Code
16
Model, View and Controller (MVC) Controller View Model Performs InputPerforms Output Write methods Read methods
17
Interactor Pattern Special Case Controller View Model Performs InputPerforms Output Write methods Read methods Interactor Facade
18
Example: Counter package models; public class ACounter implements Counter { int counter = 0; public void add (int amount) { counter += amount; } public int getValue() { return counter; }
19
Counter with MVC Pattern Controller View Model Performs InputPerforms Output add() getValue()
20
Multiple Views and Controllers Model Controller 1 Controller 2 Controller 3 Controller M View 1 View 2 View 3 View N
21
Views and Controllers are instances Model Controller 1 Controller 2 Controller 3 Controller M View 1 View 2 View 3 View N Could be instances of same class (multiple users)
22
Syncing Controllers & View Model Controller 1 Controller 2 Controller 3 Controller M Syncing Controllers and Views? View 1 View 2 View 3 View N
23
Observer/Observable Pattern Model Changed object notifies views Observable Observer Controller 1 Controller 2 Controller 3 Controller M View 1 View 2 View 3 View N
24
Observer/Observable Pattern Observable 1 Observer 1 Observer 2 Observer 3 Observer N Observable 2
25
Observer with multiple Observables A single battle simulation view observing –Multiple planes –Multiple tanks
26
Notification Scheme Observable 1 Each observer is registered with observable. Each write method in observable calls a notification method in each observer. Notification method in observer reads model. Observable 2 Each student is registered with professor’s listserv. When web page is updated mail sent to students. Student reads web page. Observer 1 Observer 2 Observer 3 Observer N
27
General Notification Scheme Observers may have multiple observerables with common notification method. Notification method parameter indicates which observable. Observable 1 Observable 2 Observer 1 Observer 2 Observer 3 Observer N
28
Model, View and Controller (MVC) Controller View Model Performs InputPerforms Output Write method Read method Notification method
29
Implementation dependent issues How does controller know about model? –Model connection method invoked on it. –By model or some other program Main Façade How is observable registered with observer. –It registers itself if it knows about observable. –Model registers it if it knows about observer. –Some other code registers it Main Facade
30
Model, View and Controller (MVC) Controller View Model Performs InputPerforms Output Write method Read method Notification method Model connection method Observer registration method
31
Counter Observable and Observer (edit) package models; public interface ObservableCounter extends Counter { } package models; public interface CounterObserver { }
32
Counter Observable and Observer (edited) package models; public interface ObservableCounter extends Counter { public void register(CounterObserver counterObserver); public void unregister(CounterObserver counterObserver); } package models; public interface CounterObserver { public void notified(ObservableCounter counter); }
33
Counter Observable and Observer package models; public interface ObservableCounter extends Counter { public void addObserver(CounterObserver observer); public void removeObserver(CounterObserver observer); } package models; public interface CounterObserver { public void update(ObservableCounter counter); } Called whenever model is updated Updated model Console View, JOption View Common interface of all views
34
Counter Model package models; import java.util.Vector; public class AnObservableCounter extends ACounter implements ObservableCounter { Vector observers = new Vector(); public void addObserver(CounterObserver observer) { observers.addElement(observer); observer.update(this); } public void removeObserver(CounterObserver observer) { observers.removeElement(observer); } void notifyObservers() { for (int observerNum = 0; observerNum < observers.size(); observerNum++) ((CounterObserver) observers.elementAt(observerNum)).update(this); } public void add (int amount) { super.add(amount); notifyObservers(); } Each write method notifies all. Give this observable initial value
35
Console View package views; import models.ObservableCounter; import models.CounterObserver; public class ACounterConsoleView implements CounterObserver { public void update(ObservableCounter counter) { appendToConsole (counter.getValue()); } void appendToConsole(int counterValue) { System.out.println("Counter: " + counterValue); }
36
JOption View package views; import models.ObservableCounter; import models.CounterObserver; import javax.swing.JOptionPane; public class ACounterJOptionView implements CounterObserver { public void update(ObservableCounter counter) { displayMessage(counter.getValue()); } void displayMessage(int counterValue) { JOptionPane.showMessageDialog(null, "Counter: " + counterValue); }
37
Console Controller Interface package controllers; import models.Counter; public interface CounterController { public void setModel (Counter theCounter); public void processInput(); }
38
Console Controller package controllers; import java.io.BufferedReader; import java.io.InputStreamReader; import models.Counter; import java.io.IOException; public class ACounterController implements CounterController { Counter counter; public void setModel (Counter theCounter) { counter = theCounter; } public void processInput() { while (true) { int nextInput = readInt(); if (nextInput == 0) return; counter.add(nextInput); } //readInt() … } Output method not called directly
39
Classes we have AnObservable Counter ACounterController ACounterConsole View ACounterJOption View
40
AConsoleControllerAndView Instances created and composed AnObservable Counter ACounterController ACounterConsole View ACounterJOption View
41
Classes we have AnObservable Counter ACounterController ACounterConsole View ACounterJOption View
42
AConsoleControllerAndJView Instances created and composed AnObservable Counter ACounterController ACounterConsole View ACounterJOption View
43
Classes we have AnObservable Counter ACounterController ACounterConsole View ACounterJOption View
44
AConsoleControllerAndViewAndJOptionView AConsoleControllerAndView ACounterJOption View Instances created and composed AnObservable Counter ACounterController ACounterConsole View
45
Console Controller And View Main package main; import models.AnObservableCounter; import facades.AConsoleControllerAndView; public class ACounterMain { public static void main(String[] args) { (new AConsoleControllerAndView()).edit(new AnObservableCounter()); }
46
ConsoleControllerAndView Facade package facades; import models.ObservableCounter; import models.CounterObserver; import controllers.ACounterController; import controllers.CounterController; import views.ACounterConsoleView; public class AConsoleControllerAndView implements CounterInteractor { public void edit(ObservableCounter model) { CounterObserver view = new ACounterConsoleView(); model.addObserver(view); CounterController controller = new ACounterController(); controller.setModel(model); controller.processInput(); } Must be last action
47
Console Controller And JOption View Main package main; import models.AnObservableCounter; import facades.AConsoleControllerAndJOptionView; public class ACounterMain { public static void main(String[] args) { (new AConsoleContollerAndJOptionView()).edit(new AnObservableCounter()); }
48
ConsoleControllerAndJView Facade package facades; import models.ObservableCounter; import models.CounterObserver; import controllers.ACounterController; import controllers.CounterController; import views.ACounterJOptionView; public class AConsoleControllerAndJOptionView implements CounterInteractor { public void edit(ObservableCounter model) { CounterObserver view = new ACounterJOptionView(); model.addObserver(view); CounterController controller = new ACounterController(); controller.setModel(model); controller.processInput(); }
49
Main with two views package main; import models.AnObservableCounter; import facades.AConsoleControllerAndViewAndJOptionView; public class ACounterMain { public static void main(String[] args) { (new AConsoleControllerAndViewAndJOptionView()).edit(new AnObservableCounter()); }
50
Facade over facade package facades; import models.ObservableCounter; import models.CounterObserver; import views.ACounterJOptionView; public class AConsoleContollerAndViewAndJOptionView implements CounterInteractor { public void edit(ObservableCounter model) { model.addObserver(new ACounterJOptionView()); (new AConsoleContollerAndView()).edit(model); }
51
Main with two views and OE package main; import models.AnObservableCounter; import bus.uigen.ObjectEditor; import facades.AConsoleControllerAndViewAndJOptionView; public class ACounterMain { public static void main(String[] args) { ObservableCounter model = new AnObservableCounter(); (new ObjectEditor()).edit(model); (new ConsoleControllerAndViewAndJOptionView()).edit(model); }
52
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. Any big brother app! Counter observer?
53
Rocket Observer Rocket added observer before view
54
AConsoleControllerAndView Instances created and composed AnObservable Counter ACounterController ACounterConsole View ARocket ARocketLauncher
55
Rocket Interface package models; import models.CounterObserver; public interface Rocket extends CounterObserver { public void launch() ; }
56
Rocket Launching Facade package models; import models.ObservableCounter; public class ARocket implements Rocket { public void update(ObservableCounter counter) { if (counter.getValue() == 0) launch(); } public void launch() { System.out.println("LIFT OFF!!!"); }
57
Rocket Launching Facade package facades; import models.ObservableCounter; import models.CounterObserver; import models.ARocket; import facades.AConsoleContollerAndView; public class ARocketLaunchCountDown implements CounterInteractor { public final int INITIAL_COUNTER_VALUE = 10; public void edit(ObservableCounter counter) { counter.add(INITIAL_COUNTER_VALUE); CounterObserver rocket = new ARocket(); counter.addObserver(rocket); (new AConsoleContollerAndView()).edit(counter); }
58
Rocket launching main package main; import models.AnObservableCounter; import models.ARocketLauncher; import facades.ARocketLaunchCountDown; public class ACounterMain { public static void main(String[] args) { (new ARocketLaunchCountDown()).edit(new AnObservableCounter()); }
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.