Outline. Observer Pattern: Pitfalls. Observer Applications

Similar documents
Outline. Design Patterns. Observer Pattern. Definitions & Classifications

are most specifically concerned with

Introduction to Software Engineering (2+1 SWS) Winter Term 2009 / 2010 Dr. Michael Eichberg Vertretungsprofessur Software Engineering Department of

6 The MVC model. Main concepts to be covered. Pattern structure. Using design patterns. Design pattern: Observer. Observers

Introduction to GUIs. Principles of Software Construction: Objects, Design, and Concurrency. Jonathan Aldrich and Charlie Garrod Fall 2014

Event-driven Programming, Separation of Concerns, the Observer pattern and the JavaFX Event Infrastructure

GUI Event Handlers (Part I)

IT 313 Advanced Application Development

Handout 14 Graphical User Interface (GUI) with Swing, Event Handling

Observer Pattern. CS580 Advanced Software Engineering October 31, Yu Sun, Ph.D.

Uppsala University. Assignment 3. Separation into Model-View TableModel ListModel ( multiple inheritance or adapter) Renderer (delegation)

Packages: Putting Classes Together

Contents Introduction 1

Solution register itself

SD Module-1 Advanced JAVA

SD Module-1 Advanced JAVA. Assignment No. 4

Lab 4. D0010E Object-Oriented Programming and Design. Today s lecture. GUI programming in

EVENTS, EVENT SOURCES AND LISTENERS

Java Event Handling -- 1

CONTENTS. Chapter 1 Getting Started with Java SE 6 1. Chapter 2 Exploring Variables, Data Types, Operators and Arrays 13

Jonathan Aldrich Charlie Garrod

M257 Past Paper Oct 2007 Attempted Solution

Graphical User Interface (GUI)

Outline. Composite Pattern. Model-View-Controller Pattern Callback Pattern

GUI DYNAMICS Lecture July 26 CS2110 Summer 2011

Observer pattern. Somebody s watching me...

GUI Program Organization. Sequential vs. Event-driven Programming. Sequential Programming. Outline

CS 180 Final Exam Review 12/(11, 12)/08

Marcin Luckner Warsaw University of Technology Faculty of Mathematics and Information Science

Software Design: Figures

Java: Graphical User Interfaces (GUI)

Multiple Choice Questions: Identify the choice that best completes the statement or answers the question. (15 marks)

Design Patterns. it s about the Observer pattern, the Command pattern, MVC, and some GUI. some more

Lecture 3: Java Graphics & Events

Basics of programming 3. Java GUI and SWING

CS410G: GUI Programming. The Model/View/Controller Pattern. Model. Controller. View. MVC is a popular architecture for building GUIs

Example Programs. COSC 3461 User Interfaces. GUI Program Organization. Outline. DemoHelloWorld.java DemoHelloWorld2.java DemoSwing.

GUI in Java TalentHome Solutions

Applet which displays a simulated trackball in the upper half of its window.

Introduction to concurrency and GUIs

ENGLISH Page 1 of 6. EXAM IN COURSE TDT4100 Object-Oriented Programming / IT1104 Programming, Advanced Course. Tuesday 29. Mai

Contents Chapter 1 Introduction to Programming and the Java Language

COMP 401 Recitation 8. Observer Pattern

Lecture 5: Java Graphics

Charlie Garrod Bogdan Vasilescu

Introduction... xv SECTION 1: DEVELOPING DESKTOP APPLICATIONS USING JAVA Chapter 1: Getting Started with Java... 1

What Is an Event? Some event handler. ActionEvent. actionperformed(actionevent e) { }

CS111: PROGRAMMING LANGUAGE II

Chapter 8. Java continued. CS Hugh Anderson s notes. Page number: 264 ALERT. MCQ test next week. This time. This place.

Class, Variable, Constructor, Object, Method Questions

Outline. More on the Swing API Graphics: double buffering and timers Model - View - Controller paradigm Applets

Java continued. Chapter 8 ALERT ALERT. Last week. MCQ test next week. This time. This place. Closed book. Assignment #2 is for groups of 3

Graphical Interface and Application (I3305) Semester: 1 Academic Year: 2017/2018 Dr Antoun Yaacoub

Overview. Lecture 7: Inheritance and GUIs. Inheritance. Example 9/30/2008

Java Fundamentals (II)

Design Patterns Design patterns advantages:

Control Flow: Overview CSE3461. An Example of Sequential Control. Control Flow: Revisited. Control Flow Paradigms: Reacting to the User

GUI Event Handlers (Part II)

Name: CSC143 Exam 1 1 CSC 143. Exam 1. Write also your name in the appropriate box of the scantron

Virtualians.ning.pk. 2 - Java program code is compiled into form called 1. Machine code 2. native Code 3. Byte Code (From Lectuer # 2) 4.

Static Detection of Brittle Parameter Typing

15CS45 : OBJECT ORIENTED CONCEPTS

Swing. By Iqtidar Ali

Course Status Networking GUI Wrap-up. CS Java. Introduction to Java. Andy Mroczkowski

Frames, GUI and events. Introduction to Swing Structure of Frame based applications Graphical User Interface (GUI) Events and event handling

The DSL created in Scala was accomplished using the Implicit conversion (Views) feature of Scala.

Graphical User Interfaces. Comp 152

AP COMPUTER SCIENCE JAVA CONCEPTS IV: RESERVED WORDS

The AWT Event Model 9

Design patterns for graphical user interface applications

Graphical User Interface (GUI)

The JFrame Class Frame Windows GRAPHICAL USER INTERFACES. Five steps to displaying a frame: 1) Construct an object of the JFrame class

Systems Programming. Bachelor in Telecommunication Technology Engineering Bachelor in Communication System Engineering Carlos III University of Madrid

Lab. Lecture 26: Concurrency & Responsiveness. Assignment. Maze Program

Caesar. Ben Rister work by Mira Mezini and Klaus Ostermann

EPITA Première Année Cycle Ingénieur. Atelier Java - J5

Bean Communication. COMP434B Software Design. Bean Communication. Bean Communication. Bean Communication. Bean Communication

Based on slides by Prof. Burton Ma

CIS 120 Final Exam May 7, Name (printed): Pennkey (login id):

Laboratorio di Tecnologie dell'informazione

PROGRAMMING DESIGN USING JAVA (ITT 303) Unit 7

Module 5 The Applet Class, Swings. OOC 4 th Sem, B Div Prof. Mouna M. Naravani

Programming Languages and Techniques (CIS120)

Swing from A to Z Some Simple Components. Preface

Introduction to the JAVA UI classes Advanced HCI IAT351

SYSC Come to the PASS workshop with your mock exam complete. During the workshop you can work with other students to review your work.

Lecture 9. Lecture

Swing UI. Powered by Pentalog. by Vlad Costel Ungureanu for Learn Stuff

CSE 331 Software Design & Implementation

Graphics. Lecture 18 COP 3252 Summer June 6, 2017

Table of Contents. Chapter 1 Getting Started with Java SE 7 1. Chapter 2 Exploring Class Members in Java 15. iii. Introduction of Java SE 7...

Block I Unit 2. Basic Constructs in Java. AOU Beirut Computer Science M301 Block I, unit 2 1

DOWNLOAD PDF CORE JAVA APTITUDE QUESTIONS AND ANSWERS

Problems with Concurrency. February 19, 2014

Graphical User Interface (GUI) components in Java Applets. With Abstract Window Toolkit (AWT) we can build an applet that has the basic GUI

EXAMPLE ANSWERS. EXAM IN COURSE TDT4100 Object-Oriented Programming / IT1104 Programming, Advanced Course. Tuesday 29. Mai

Composite Pattern Diagram. Explanation. JavaFX Subclass Hierarchy, cont. JavaFX: Node. JavaFX Layout Classes. Top-Level Containers 10/12/2018

Graphical interfaces & event-driven programming

Sri Vidya College of Engineering & Technology


Transcription:

Outline Observer Pattern: Pitfalls NotifyObservers Invocation Problem M:N Problem ConcurrentModificationException Problem Cyclic Dependency Problem Causality of State Changes Problem Memory Management Problem Multi Model Problem Observer Applications 23 March 2018 1

Observer Pattern: Structure Structure diagram Subject and Concrete Subject may be combined in a single class Observer may be an interface 23 March 2018 2

Observer Pattern: Collaborations :ConcreteSubject :ConcreteObserver :ConcreteObserver setstate notify update update 23 March 2018 3

Observer Pattern: Sample Code (1/2) interface Observer { void update(); abstract class Observable { private final List<Observer> observers = new ArrayList<>(); public void addobserver(observer o) { observers.add(o); public void removeobserver(observer o) { observers.remove(o); protected void notifyobservers() { for(observer obs : observers) { obs.update(); 23 March 2018 4

Observer Pattern: Sample Code (2/2) class Sensor extends Observable { private int temp; public int gettemperature() { return temp; public void settemperature(int val) { temp = val; notifyobservers(); class SensorObserver implements Observer { private Sensor s; SensorObserver (Sensor s) { this.s = s; s.addobserver(this); public void update() { System.out.println("Sensor has changed, new temperature is " + s.gettemperature()); 23 March 2018 5

Invocation of notifyobservers When is notifyobservers called Automatically at every state change => many updates Explicitly after a set of change operations => client responsibility Approaches to reduce number of updates Asynchronous update at idle time AWT/Swing repaint registers an asynchronous request that this component needs to be repainted => multiple calls to repaint may be combined Here, "observer" is the actual "paint" method which reacts on changes java.util.observable: explicit, but change operations call setchanged notifyobservers becomes only active if ischanged() == true (notifyobservers calls clearchanged) notifyobservers could be invoked regularly (as a background task) Registration for specific message types only To be checked within observable class 23 March 2018 6

java.util.observable public interface Observer { void update(observable o, Object arg); public class Observable { private boolean changed = false; // Marks this Observable as having been changed protected void setchanged() { changed = true; // Indicates that this object has no longer changed, // or that it has already notified all of its observers // of its most recent change. protected void clearchanged() { changed = false; // Tests if this object has changed. public boolean haschanged() { return changed; 23 March 2018 7

java.util.observable // If this object has changed, as indicated by the // haschanged method, then notify all of its observers // and then call the clearchanged method to indicate // that this object has no longer changed. public void notifyobservers(object arg) { if (!changed) return; Object[] copy = obs.toarray(); clearchanged(); // before notification! for (int i = copy.length-1; i>=0; i--) ((Observer)copy[i]).update(this, arg);... 23 March 2018 8

Missing Multiple Inheritance java.util.observable Provides implementation of an Observable Can only be used if extension is not defined in its own inheritance hierarchy Model Observable * Observer Consequence Code duplication java.util.observable is not used in the Java library (and will be removed) Solution Composition (twin classes) ObservableModel 23 March 2018 9

Observable Twin Classes Twin Classes Model Observable * Observer Observable- Model Observer- Registry getsource Concrete- Observer ObservableModel can be used where Models are expected ObserverRegistry can be used where Observables are expected public class Model { private int value; public int getvalue() { return value; public void setvalue(int value) { this.value = value; 23 March 2018 10

Observable Twin Classes Twin Classes public class ObservableModel extends Model { private final ObserverRegistry<Model> reg = new ObserverRegistry<>(this); public Observable getobservable() { return reg; public void addobserver(observer obs) { this.reg.addobserver(obs); @Override public void setvalue(int value) { super.setvalue(value); reg.setchanged(); reg.notifyobservers(); 23 March 2018 11

Observable Twin Classes Twin Classes public class ObserverRegistry<T> extends Observable { private final T owner; public ObserverRegistry(T trueobservable) { this.owner = trueobservable; public T gettrueobservable() { return owner; // lift visibility into this package protected void setchanged() { super.setchanged(); protected void clearchanged() { super.clearchanged(); Lifting necessary. setchanged is declared protected, but in another package! 23 March 2018 12

Observable Twin Classes Twin Classes public class PrintObserver implements Observer { public void update(observable obs, Object arg) { Model m = ((ObserverRegistry<Model>) obs).gettrueobservable(); System.out.println("new value: " + m.getvalue()); public class Test { public static void main(string[] args) { ObservableModel model = new ObservableModel(); Observer obs = new PrintObserver(); model.addobserver(obs); model.setvalue(5); model.setvalue(10); 23 March 2018 13

Many Observables / Observers Observable Observable Observable Observable Observable Observer Observer Observer Observer Observer 23 March 2018 14

Many Observables / Observers Observable Observable Observable Observable Observable Observer Observer Observer Observer Observer 23 March 2018 15

Many Observables / Observers Observable Observer Mediator public class Mediator extends Observable implements Observer { public void update(object source, Object arg){ notifyobservers(source, arg); 23 March 2018 16

Problem: Concurrent Modification in notify public void addobserver(observer o) { observers.add(o); public void removeobserver(observer o) { observers.remove(o); protected void notifyobservers(object arg) { for(observer obs : observers) { obs.update(this, arg); Problem: ConcurrentModificationException Collection over which one iterates must not be changed public class OnceObserver implements Observer { public void update(observable source, Object arg) { System.out.println("received update from "+source); source.removeobserver(this); 23 March 2018 17

Problem: Concurrent Modification in notify Solution 1: Perform notification on a copy of the observer list protected void notifyobservers() { Observer[] copy; copy = observers.toarray(new Observer[observers.size()]); for (Observer obs : copy) { obs.update(this); protected void notifyobservers() { for(observer o : new ArrayList<>(observables)) { o.update(this); 23 March 2018 18

Problem: Concurrent Modification in notify Solution 2: Delay add/removeobserver calls private static class Mutation { private final Observer observer; private final boolean add; public Mutation(Observer observer, boolean add) { this.observer = observer; this.add = add; private List<Mutation> pendingmutations = new LinkedList<>(); private int level = 0; public void addobserver(observer o) { if(level > 0) { pendingmutations.add(new Mutation(o, true)); else { observers.add(o); public void removeobserver(observer o) { if(level > 0) { pendingmutations.add(new Mutation(o, false)); else { observers.remove(o); 23 March 2018 19

Problem: Concurrent Modification in notify... protected void notifyobservers() { level++; for (Observer obs : observers) obs.update(this); level--; if(level == 0) { for(mutation m : pendingmuts) { if(m.add) observers.add(m.observer); else observers.remove(m.observer); pendingmutations.clear(); 23 March 2018 20

Problem: Concurrent Modification in notify Solution 3: Copy the observer list upon modification private List<Observer> observers = new CopyOnWriteArrayList<>(); public void addobserver(observer o) { observers.add(o); public void removeobserver(observer o) { observers.remove(o); protected void notifyobservers(object arg) { for(observer obs : observers) { obs.update(this, arg); CopyOnWriteArrayList is a (thread-safe) variant of ArrayList in which all mutative operations are implemented by making a fresh copy of the underlying array. 23 March 2018 21

Problem: Cyclic Dependencies ItemListener JCheckBox- MenuItem ColorModel ColorListener 23 March 2018 22

Problem: Cyclic Dependencies Notification Sequence 23 March 2018 23

Problem: Cyclic Dependencies Solution 1: Break recursion in the color listener implementation public void colorvaluechanged(color c) { if (isselected()!= c.equals(this.color)) setselected(c.equals(this.color)); Solution 2: Break recursion in (subclass of) JCheckBoxMenuItem public void setselected(boolean b) { if (b!= isselected()) super.setselected(b); 23 March 2018 24

Problem: Cyclic Dependencies Solution 3: Break recursion in ItemListener implementation private boolean updating = false; public void itemstatechanged(itemevent e) { if(!updating) { updating = true; if (e.getstatechange() == ItemEvent.SELECTED) { model.setcolor(color); updating = false; instead of comparing the value to be set on the model with the existing value, this solution checks for recursive invocations using a flag => changes performed during a notification would not be handled 23 March 2018 25

Problem: Cyclic Dependencies Solution 4: Break recursion in the color model public class ColorModel { private Color color; public void setcolor(color color) { if (!color.equals(this.color)) { this.color = color; notify(color);... General rule: Propagate changes only if the model really changed 23 March 2018 26

Problem: Cyclic Dependencies Solution 5: Use ActionListener instead of an ItemListener Actions are only fired if an event is initiated over the keyboard or over the mouse Whenever the color is changed over the ColorModel, then the JCheckBoxMenuItem is changed and an ItemEvent is fired, but no listener is registered for that and thus the recursion is broken General Rule: Avoid recursion! Always break the recursion in a model 23 March 2018 27

Problem: Causality of Changes Causality How can we assert that notifications appear at the Observers in the same order as they were applied to the model 23 March 2018 28

Example Observable Document Observers CorrectionListener TextFieldListener Operation (c) is added in front of FHNW 23 March 2018 29

Problem: Causality of Changes Solutions Queuing of notifications: Notifications triggered by recursive state changes are delayed until all pending changes have been notified Model and notifications are out of sync, i.e. when an insert character is notified, this character may already have been removed from the model Queuing of state changes Model becomes asynchronous, i.e. state change operations are not executed immediately => difficult to program Prohibit state changes during notification 23 March 2018 30

Problem: Memory Management Example ActionListener * 1 Multicast- Panel newbutton new: JButton {Creates closeallbutton closeall: JButton SimpleFrame buf 23 March 2018 31

Problem: Memory Management MulticastPanel: ActionListener (new button) SimpleFrame f = new SimpleFrame(); f.settitle("window " + counter++); f.setsize(250, 150); f.setvisible(true); closeallbutton.addactionlistener(f); SimpleFrame: ActionListener (close all button) public void actionperformed(actionevent evt) { this.dispose(); // Releases all of the native screen // resources used by this window 23 March 2018 32

Problem: Memory Management Memory Leaks Despite the existence of a GC, memory leaks can occur Remember to remove registered observers before you release an object public void actionperformed(actionevent evt) { JButton closeallbutton = (JButton)evt.getSource(); closeallbutton.removeactionlistener(this); this.dispose(); Alternative solution: use weak references means that the listener is only registered in the observable as long as there exists a strong reference to it 23 March 2018 33

Problem: What is the model Multi-Models Assume that we represent each channel of our color as a separate model Simplifies implementations of the scrollbars / textfields red green blue Consequences Rules Each change of the color implies three updates Modelling is too fine granular, actually implementation details are published (like the representation of the color as RGB or HSV) Only changes from valid to valid state should be visible 23 March 2018 34

Outline Observer Pattern: Pitfalls Observer Applications Model-View Separation in Swing Other applications 23 March 2018 35

Model-View Separation in Swing All Swing controls refer to a model Model contains the data Model informs registered views when state changes View visualizes data View getmodel() setmodel(model m) * 1 Model Examples: JButton (ButtonModel) JScrollBar (BoundedRangeModel) JList (ListModel) JTree (TreeModel) JMenu (ButtonModel) 23 March 2018 36

Model-View Separation in Swing View: setmodel If the model is set on a view, then the view registers itself (or an explicit listener implementation) as an observer of the model class View { private Model model; public Model getmodel(){ return model; public void setmodel(model model){ Model m = getmodel(); if(m!= null){ m.removemodellistener(ml); this.model = model; model.addmodellistener(ml);... 23 March 2018 37

Model-View Separation in Swing Applications Several Controls may refer (display) the same model JTextField field = new JTextField(10); JPasswordField pwfld = new JPasswordField(10); JTextArea area = new JTextArea(5, 20); pwfld.setdocument(field.getdocument()); area.setdocument(field.getdocument()); 23 March 2018 38

Model-View Separation in Swing Applications Model may be implemented by user Example: ListModel interface ListModel { getsize(); getelementat(int i); adddatalistener(datalistener dl); removedatalistener(datalistener dl); List entries can be computed on demand List entries can be fetched from data base ListModel may dynamically change its content 23 March 2018 39

Model-View Separation in Swing Example: Fibonacci-Model N-th fibonacci number is computed on demand JList list = new JList( new AbstractListModel() { public int getsize() { return 10000; public Object getelementat(int n) { if(n == 0) return BigInteger.ZERO; BigInteger f0 = BigInteger.ZERO; BigInteger f1 = BigInteger.ONE; List entries can be computed on demand for(int i=1; i<n; i++) { List BigInteger entries can f2 be fetched = f0.add(f1); from data f0 base = f1; f1 = f2; ListModel may dynamically change its content return f1; ); 23 March 2018 40

Observer Pattern: Other Applications AWT Event handling ActionListener, MouseListener, MouseMotionListener, Swing: Model-View separation JTable, JList Java Beans Event Notifications public void addpropertychangelistener(propertychangelistener) public void removepropertychangelistener(propertychangelistener) public void addvetoablechangelistener(vetoablechangelistener) public void removevetoablechangelistener(vetoablechangelistener) JavaFX data binding 23 March 2018 41

JavaFX Data Binding 23 March 2018 42

JavaFX Data Binding ChangeListener Can be added to every ObservableValue void addlistener(changelistener<? super T> listener); Change listener is invoked as soon as the value changes If the value is not changed => no invocation => no cycles Both the old and the new value is passed to the listener textfield.textproperty().addlistener( (observable, oldvalue, newvalue) -> { //... ); 23 March 2018 43

JavaFX Data Binding Data Binding Properties can be bound unidirectionallly or bidirectionally StringProperty p1 = new SimpleStringProperty("p1"); IntegerProperty p2 = new SimpleIntegerProperty(); p2.bind(p1.length()); The value of p2 can no longer be set, but it depends on p1 StringProperty prop1 = new SimpleStringProperty(""); StringProperty prop2 = new SimpleStringProperty(""); prop2.bindbidirectional(prop1); If one value changes, the other is adjusted automatically 23 March 2018 44

JavaFX Data Binding Bidirectional Binding public static <T> BidirectionalBinding bind( Property<T> property1, Property<T> property2) { BidirectionalBinding binding = new TypedGenericBidirectionalBinding<T>(property1, property2); property1.setvalue(property2.getvalue()); property1.addlistener(binding); property2.addlistener(binding); return binding; 23 March 2018 45

JavaFX Data Binding Bidirectional Binding private static class TypedGenericBidirectionalBinding<T> { private final WeakReference<Property<T>> propertyref1; private final WeakReference<Property<T>> propertyref2; private boolean updating = false; public void changed(observablevalue<? extends T> sourceproperty, T oldvalue, T newvalue) { if (!updating) { final Property<T> p1 = propertyref1.get(); final Property<T> p2 = propertyref2.get(); if ((p1 == null) (p2 == null)) { if (p1!= null) { p1.removelistener(this); if (p2!= null) { p2.removelistener(this); else { updating = true; if (p1 == sourceproperty) { p2.setvalue(newvalue); else { p1.setvalue(newvalue); updating = false; 23 March 2018 46