Download presentation
Presentation is loading. Please wait.
Published byStephany Harrison Modified over 8 years ago
1
My Observer Goes to 11 Model-View Controller 1
2
Which is the best class diagram? 2 ___Edge___ drop() _Vertex_ addEdge() dropEdge() _Iterable_ * 2 ___Edge___ _Vertex_ * 2 drop addEdge dropEdge ___Edge___ drop() _Vertex_ addEdge() dropEdge() * 2 A B C class Edge { Vertex a, b; Edge (a1, b1) { a = a1; b = b1; a1.insertEdge(this); b1.insertEdge(this); } void drop () { if (a.hasEdge(this)) a.dropEdge(); if (b.hasEdge(this)) b.dropEdge(); a = null; b = null; } … } class Vertex { Set edges; … void addEdge (Edge e) { edges.add(e); } // no dangling edges! void dropEdge (Edge e) { edges.remove(e); e.drop(); } … } B: boxes denote types, not methods; there is no implementing of Iterable.
3
What’s wrong with this design? class Edge { Vertex a, b; Edge (a1, b1) { a = a1; b = b1; a1.insertEdge(this); b1.insertEdge(this); } void drop () { if (a.hasEdge(this)) a.dropEdge(); if (b.hasEdge(this)) b.dropEdge(); a = null; b = null; } … } class Vertex { Set edges; … void addEdge (Edge e) { edges.add(e); } // no dangling edges! void dropEdge (Edge e) { edges.remove(e); e.drop(); } … } A. It’s too complicated (why?) B. Violates SRP (how?) C. There’s a loop in the dependences (where & why bad?) D. All of the above 3 ___Edge___ drop() _Vertex_ addEdge() dropEdge() * 2 The work ( responsibility ) of keeping the relationships correct is shared too much between the objects, resulting in a loop in the dependences and complex logic to avoid infinite recursion. This is he motivation for the Mediator Pattern.
4
Mediator Pattern When in doubt add a level of indirection 4
5
myCity Story: Show Friends on Map 5 class Friend { Location location(); // null −> not-known boolean online(); Bitmap image(); } class Friends implements Iterable { Friends online(); Friends locationKnown(); // −> online? } Given I am logged in And my location is known When my friends are online And my friends’ location is known And my friends are near me Then I see them on the map How get friends drawn on the map? What thing does something to itself so friends get drawn on map?
6
Nearby Friends: Subclass Approach 6 __NearbyFriendsMap__ - GoogleMap map - Friends friends −−−−−−−−−−−−−−−−− + showNearbyFriends() _________Friends_________ - List friends −−−−−−−−−−−−−−−−− + Friends online() + Friends locationKnown() _GoogleMap_ … _________Friend_________ + boolean online() + Location location() + Bitmap image() * _Iterable_ … Actually has good SRP superclass does map subclass does friends but: “is-a” map or “has-a” friends? “has” all kinds of things, incl. friends DP says subclassing is usually inferier Anyway, we can’t subclass GoogleMap Actually has good SRP superclass does map subclass does friends but: “is-a” map or “has-a” friends? “has” all kinds of things, incl. friends DP says subclassing is usually inferier Anyway, we can’t subclass GoogleMap
7
Nearby Friends: Mediator Approach 7 _NearbyFriendsTracker_ - GoogleMap map - Friends friends −−−−−−−−−−−−−−−−− + showNearbyFriends() _________Friends_________ - List friends −−−−−−−−−−−−−−−−− + Friends online() + Friends locationKnown() _GoogleMap_ … _________Friend_________ + boolean online() + Location location() + Bitmap image() * _Iterable_ … This is a mediator design solves problem of complex inter- object relationship (friends Map) lets each focus on their single responsibility This is a mediator design solves problem of complex inter- object relationship (friends Map) lets each focus on their single responsibility
8
Mediator Pattern Name: Mediator Problem: Object interactions or relationships are complex or interdependent Solution: Introduce an object whose responsibility is mediating the interactions or maintaining the relationships, removing those responsibilities from the mediated objects 8
9
Model-View Controller Once again, the ten-cent version 9
10
How should NFT get called, by whom? 10 _NearbyFriendsTracker_ - GoogleMap map - Friends friends −−−−−−−−−−−−−−−−− + showNearbyFriends() _________Friends_________ - List friends −−−−−−−−−−−−−−−−− + Friends online() + Friends locationKnown() _GoogleMap_ … _________Friend_________ + boolean online() + Location location() + Bitmap image() * _Iterable_ … How does NearbyFriendsTracker get called when Friends changes? A.Rename showNearbyFriends to “update” B.Put NFT in its own thread and have it poll friends for changes, call sNF C.Observer pattern: Make Friends a “subject” and NFT an “observer” of it D.Observer pattern: Make Friend a “subject” and NFT an “observer” of it How does NearbyFriendsTracker get called when Friends changes? A.Rename showNearbyFriends to “update” B.Put NFT in its own thread and have it poll friends for changes, call sNF C.Observer pattern: Make Friends a “subject” and NFT an “observer” of it D.Observer pattern: Make Friend a “subject” and NFT an “observer” of it
11
Discussion 11 A: No. SNF is like the “display” method in ForecastDisplay. We need a separate “update” or “changed” method, which will call SNF B:You could do that, but it’s massively inefficient, since Friend status changes rarely. Also, complex – hard to understand, debug, etc. Overkill C: Yes. Recall that Observer is called Listener in Android and Java in general D: No, that defeats the whole purpose of Friends as an aggregator class. See C.
12
How should NFT get called, by whom? 12 _NearbyFriendsTracker_ - GoogleMap map - Friends friends −−−−−−−−−−−−−−−−− + showNearbyFriends() _________Friends_________ - List friends −−−−−−−−−−−−−−−−− + Friends online() + Friends locationKnown() _GoogleMap_ … _________Friend_________ + boolean online() + Location location() + Bitmap image() * _Iterable_ … How does NearbyFriendsTracker get called when GoogleMap changes (e.g., you move)? A.Observer pattern: have NFT observe your location through LocationManager B.Observer pattern: Make Friends a “subject” and NFT an “observer” of it C.Observer pattern: Make GoogleMap a “subject” and NFT an “observer” of it How does NearbyFriendsTracker get called when GoogleMap changes (e.g., you move)? A.Observer pattern: have NFT observe your location through LocationManager B.Observer pattern: Make Friends a “subject” and NFT an “observer” of it C.Observer pattern: Make GoogleMap a “subject” and NFT an “observer” of it
13
Discussion 13 A: No. That’s just one way the view port on the map changes B: No. That was for dealing with changes to Friends online status and location, not map’s changing view port C: Yes. That’s the idea. Of course, GM is final, but it already has a register method and all, like LocationManager.
14
Mediator + Observer (x 2) 14 _NearbyFriendsTracker_ - GoogleMap map - Friends friends −−−−−−−−−−−−−−−−− + showNearbyFriends() _________Friends_________ - List friends −−−−−−−−−−−−−−−−− + Friends online() + Friends locationKnown() _GoogleMap_ … _________Friend_________ + boolean online() + Location location() + Bitmap image() * _Iterable_ … _____FriendsListener____ onFriendOnline(Friend) onFriendOffline(Friend) onFriendMove(Friend) _____OnCameraChangeListener____ onCameraChange(CameraPosition) _FriendSubject_ register, notify, … * * It’s more than Observer x 2 because NFT directly queries and manipulates Friends and GMap to maintain the relationship between the two. Observer just “observes”, it doesn’t manipulate.
15
MVC Object Interactions 15 a NearbyFriendsTracker a Friends a GoogleMap onFriendMove(Friend), etc. onCameraChange(CameraPosition) gm.addMarker(…), etc. friends.registerObserver(this) gm.setOnCameraChangeListener(this)
16
Who “knows about” who? Knows about: Type A knows about Type B if A calls or uses B in any way A.Friends knows NFT, which knows Gmap B.Friends and GMap know about NFT C.NFT knows about Friends and Gmap D.NFT, Friends, & GMap all know about each other 16
17
Discussion of who knows about who Best Answer - C : NFT knows about Friends and Gmap Technically NFT doesn’t even know about Friends, just the FriendsSubject interface. In theory this allows NFT to integrate other implementations of “friends”, as long as they implement the FriendsSubject It’s the only one making direct calls on the other objects Although Friends and GMap make callbacks on NFT, those are methods first declared in the interfaces Friends and GMap know about those interfaces, but not the classes that implement the methods This “separation of concerns” allows NFT to glue together Friends and GoogleMap, without either having to know about the other They do have to anticipate that something wants to observe them, but they don’t know who that is, just that they implement their observers 17
18
Model-View Controller Terminology Model : the “data”; also known as Subject (Friends) View : the visualization of the data, often a UI (Gmap) Controller: mediator that manages the relationships MVC handles two limitations of Observer View is not just a passive view (e.g., a visualization) a UI where the View changes to an alternate view View makes changes to the Model Model and View pre-exist Can’t use Observer pattern because View doesn’t implement Observer interface for Subject/Model So, what do you do when you want to connect two pre-existing, incompatible components? 18
19
Ten-Cent MVC: Class Diagram 19 _Controller___Model__ … _View_ … __ModelListener__ update(…) _ViewListener_ update(…) _ModelSubject_ register, notify, … * _ViewSubject_ register, notify, … *
20
Design Patterns Now experience doesn’t have to be a cruel teacher 20 THE BOOK, by “Gang of Four”
21
SRP &10-cent OO Design aren’t Enough Slow, focus on “external” entities (e.g., friends, maps) Experience can help us take big, fast leaps But experience takes years to acquire Design Patterns method is a shared vocabulary of software design experience Concise way to talk about designs Focused on making software change easier Reduce coupling caused by object interactions When one class changes, causes another to change When a “big” class has changes that are mixed in with parts that don’t 21
22
Design Pattern A template for how to solve a problem that can be used in many different situations (wikipedia) A pattern consists of (at least): 1.A name 2.A problem statement 3.A solution: description, example, class diagram Best practice: name our code after the pattern E.g., NearbyFriendsTracker would be FriendsMapMediator or FriendsMapController (it’s more than an observer, since it updates Model and View) Used only as-needed (if it ain’t broke, don’t fix it) Use of design patterns adds complexity (and takes precious time!) Cost vs. benefit 22
23
Take-Aways When in doubt, add a level of indirection Mediator, Controller (in MVC) Achieving loosely coupled designs is difficult A lot of added complexity – use only as needed Design patterns method is a concise way to share experience and talk about designs Composite design patterns If an object collaboration has multiple problems, it may require multiple patterns Patterns can be blended together to address all the problems Here: Observer and Mediator 23
24
Which is less coupled (subj-obs)? A.Original “parameter passing” design B.Revised “call object” design 24 A B
25
Which is less coupled? (Discussion) In parameter-passing design, the interface has to change, which is unfortunate In the call-object design, the body of the method still has to be modified Really, the interface has changed, but it was invisible Quite possible that only a subset of Observers are affected (e.g., only ones depending on pressure) Book likes this design (and it is quite common) I say that it’s worse because ForecastDisplay knows about WeatherData, which is “more” than knowing about WeatherSubject: wider interface, and a concrete class There is a third solution interface WeatherObserver { updatePressure(float pressure); updateTemperature(float temp); updateHumidity(float humidity); } Preferred if values change individually Maybe less preferred if they tend to change together 25
26
Revisiting Weather Station 26 save do can call removeObserver
27
Class Diagram View 27
28
Where is the violation of SRP? A.update(…) both updates pressure and redraws display B.Manages weatherSubject and forecast display C.Implements both Observer and DisplayElement D.Maintains current pressure and last pressure 28
29
Upgrading Weather Station 1.Add display for Temp, using existing “meter” 2.Able to pause display 29
30
Extreme example: both listen to each other 30 (Observer) (Subject) (& Observer) (& Subject) I need your state (in call-object design) Imagine a graph made up of classes Vertex and Edge: If I delete a vertex, edges have to go If I delete an edge, vertices need to update Should both be models of each other?
31
When in doubt, add a level of indirection We have a “double” Observer pattern Controller is implementing the Mediator pattern Fully decouples SubjectA and SubjectB Book’s version is not full mediator because View still Observes Model 31 (Observer) (Subject) (& Observer) (& Subject) I need your state A B changeA()
32
In our last episode… Observer, Listener, Publish-Subscribe 32
33
Observer motivation 33
34
Discussion Recall: Open/Closed Principle Classes should be open to extension but closed to modification Recall: Code to interfaces, not implementations 34
35
Three interfaces (TWO in the pattern) 35 Since update() is kind of specific, I’d call this WeatherObserver
36
Observer Implementation (aka Listener) 36
37
UML View 37 Note that this functions as an Adapter between Subject and DisplayElement!
38
Wrapping up Observer Remember, it might be called Listener or Publish-Subscribe 38 registerObserver notifyObservers
39
Why we call this “event-driven” Normally, if an object C wants newest data from another object P, it just makes the call: Problem is that object C doesn’t know when to make the call (when a newer value is available for P) That’s why we had the call go the other way (P calling C): With the observer pattern, the P to C call (Subject to Observer) acts like an event because the call is going the “other” or “wrong” way Yet P does not “know about” C, it only knows about the Observer interface (i.e., not about ForecastDisplay) 39 registerObserver notifyObservers
40
Coupling in Observer Coupling is the property that when one thing changes, another thing may have to change (they are coupled) Want loosely coupled designs 40 Note that Observer is “coupled” to weather generically, and hence to WeatherData generally Indeed, the designer of WeatherData chooses the Observer interface ForecastDisplay can’t be implemented until Observer has been worked out
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.