Module dependences and decoupling (Events, listeners, callbacks)

Similar documents
CSE 331 Software Design and Implementation. Lecture 17 Events, Listeners, Callbacks

CSE 331 Software Design and Implementation. Lecture 16 Callbacks and Observers

Design Patterns So Far. Design Patterns, cont. Design Patterns So Far. Outline

CS5010 PDP Introduction to Design. Maria Zontak. Slides inspired by slides of H.Perkins (UW, CS331) and MIT software engineering course

EINDHOVEN UNIVERSITY OF TECHNOLOGY

Design Patterns Design patterns advantages:

CSE 331 Software Design & Implementation

Foundations of object orientation

Design Patterns. CSC207 Fall 2017

Tuesday, October 4. Announcements

Last Time: Object Design. Comp435 Object-Oriented Design. Last Time: Responsibilities. Last Time: Creator. Last Time: The 9 GRASP Patterns

CS 160: Interactive Programming

Java Object Oriented Design. CSC207 Fall 2014

18.1 Definitions and General OO Principles

Design Patterns: Structural and Behavioural

Design Patterns. CSC207 Winter 2017

Objects First with Java

Object Oriented Programming

Organization of User Interface Software

More About Objects. Zheng-Liang Lu Java Programming 255 / 282

1 Shyam sir JAVA Notes

Lethbridge/Laganière 2005 Chapter 9: Architecting and designing software 6

Top Down Design vs. Modularization

Client Code - the code that uses the classes under discussion. Coupling - code in one module depends on code in another module

COURSE 2 DESIGN PATTERNS

CSE 331 Final Exam 3/16/15 Sample Solution

Inheritance. Inheritance Reserved word protected Reserved word super Overriding methods Class Hierarchies Reading for this lecture: L&L

Object-Oriented Concepts

CSE 403 Lecture 8. UML Class Diagrams. Thanks to Marty Stepp, Michael Ernst, and other past instructors of CSE 403

A4 Explain how the Visitor design pattern works (4 marks)

CSE 331. Model/View Separation and Observer Pattern

Outline. Object Oriented Programming. Course goals. Staff. Course resources. Assignments. Course organization Introduction Java overview Autumn 2003

Chapter 2: The Object-Oriented Design Process

From Design Patterns: Elements of Reusable Object Oriented Software. Read the sections corresponding to patterns covered in the following slides.

CSE 219 COMPUTER SCIENCE III STRUCTURAL DESIGN PATTERNS SLIDES COURTESY: RICHARD MCKENNA, STONY BROOK UNIVERSITY.

CSE 331 Software Design & Implementation

Design Patterns. Definition of a Design Pattern

CSE331 Spring 2015, Final Examination June 8, 2015

CSE 331 Software Design & Implementation

Introduction to concurrency and GUIs

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

Relationships Between Real Things CSE 143. Common Relationship Patterns. Employee. Supervisor

CSE wi Final Exam 3/12/18 Sample Solution

CSE 70 Final Exam Fall 2009

Self-test Java Programming

Relationships Between Real Things. CSE 143 Java. Common Relationship Patterns. Composition: "has a" CSE143 Sp Student.

Design Pattern What is a Design Pattern? Design Pattern Elements. Almas Ansari Page 1

PRINCIPLES OF SOFTWARE BIM209DESIGN AND DEVELOPMENT 00. WELCOME TO OBJECTVILLE. Speaking the Language of OO

Info 408 Distributed Applications Programming Exercise sheet nb. 4

Jonathan Aldrich Charlie Garrod

OBJECT ORİENTATİON ENCAPSULATİON

Object-Oriented Concepts and Design Principles

Logistics. Final Exam on Friday at 3pm in CHEM 102

Model-View-Controller

Chapter 12. OOP: Creating Object-Oriented Programs The McGraw-Hill Companies, Inc. All rights reserved. McGraw-Hill

Lecture 19 GUI Events

Java s Implementation of Concurrency, and how to use it in our applications.

Overview of Eclipse Lectures. Module Road Map

Chapter 5 Object-Oriented Programming

System Design. Design Issues. System Design. System Design. Design: HOW to implement a system. Strategic vs. Local Design Decisions.

SOFTWARE PATTERNS. Joseph Bonello

Core Java - SCJP. Q2Technologies, Rajajinagar. Course content

CO Java SE 8: Fundamentals

Design: HOW to implement a system

Design Patterns. Comp2110 Software Design. Department of Computer Science Australian National University. Second Semester

CSCU9T4: Managing Information

Assigning Responsibilities (Patterns of Responsibility Assignment Principles: GRASP)

Case studies: Outline Case Study: Noughts and Crosses

System Design. Design: HOW to implement a system

Inheritance (Part 2) Notes Chapter 6

CSE wi Final Exam 3/12/18. Name UW ID#

Computation Abstractions. Processes vs. Threads. So, What Is a Thread? CMSC 433 Programming Language Technologies and Paradigms Spring 2007

IT101. Inheritance, Encapsulation, Polymorphism and Constructors

Comp-304 : Object-Oriented Design What does it mean to be Object Oriented?

Midterm assessment - MAKEUP Fall 2010

Inheritance and Substitution (Budd chapter 8, 10)

Object Oriented Programming: In this course we began an introduction to programming from an object-oriented approach.

Cosc 241 Programming and Problem Solving Lecture 9 (26/3/18) Collections and ADTs

From Module To Objects

P2: Collaborations. CSE 335, Spring 2009

CH. 2 OBJECT-ORIENTED PROGRAMMING

n HW5 out, due Tuesday October 30 th n Part 1: Questions on material we ll cover today n Part 2: BFS using your graph from HW4

Outline. Subtype Polymorphism, Subtyping vs. Subclassing, Liskov Substitution Principle. Benefits of Subtype Polymorphism. Subtype Polymorphism

CSE373 Fall 2013, Second Midterm Examination November 15, 2013

Chapter 6 Introduction to Defining Classes

Java Swing Introduction

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

COP 3330 Final Exam Review

3 Getting Started with Objects

Fast Track to Core Java 8 Programming for OO Developers (TT2101-J8) Day(s): 3. Course Code: GK1965. Overview

Chair of Software Engineering. Languages in Depth Series: Java Programming. Prof. Dr. Bertrand Meyer. Exercise Session 10

2. (True/False) All methods in an interface must be declared public.

CS342: Software Design. November 21, 2017

CMSC 433 Programming Language Technologies and Paradigms. Spring 2013

Inf1-OOP. OOP Exam Review. Perdita Stevens, adapting earlier version by Ewan Klein. March 16, School of Informatics

OOP Design Conclusions and Variations

LECTURE 3: SOFTWARE DESIGN. Software Engineering Mike Wooldridge

ECE 3574: Dynamic Polymorphism using Inheritance

Safety SPL/2010 SPL/20 1

1B1b Inheritance. Inheritance. Agenda. Subclass and Superclass. Superclass. Generalisation & Specialisation. Shapes and Squares. 1B1b Lecture Slides

Transcription:

Module dependences and decoupling (Events, listeners, callbacks) CSE 331 University of Washington Michael Ernst

The limits of scaling What prevents us from building huge, intricate structures that work perfectly and indefinitely? No friction No gravity No wear-and-tear the difficulty of managing complexity (e.g., understanding them) Solution: Modularity, and minimize interactions

Interactions cause complexity To simplify, split design into parts that don't interact much Coupling: amount of interaction between parts Cohesion: similarity within a part MY MY MY FINAL PROJECT FINAL PROJECT FINECT PROJAL An application A poor decomposition (parts strongly coupled) Not the obvious decomposition, but better (parts weakly coupled)

Design exercise #1 Write a typing break reminder program Remind the user about Repetitive Strain Injury, and encourage the user to take a break from typing Naive design: Main program makes a timer Timer loop performs action periodically Action = display messages and offer exercises (Let's ignore multi-threaded solutions for this discussion)

TimeToStretch suggests exercises public class TimeToStretch { public void run() { System.out.println("Stop typing!"); suggestexercise(); public void suggestexercise() {...

Timer calls run() periodically public class Timer { private TimeToStretch tts = new TimeToStretch(); public void start() { while (true) {... if (enoughtimehaspassed) { tts.run();...

Main class puts it together class Main { public static void main(string[] args) { Timer t = new Timer(); t.start(); This program, as designed, will work... But we can do better

Module dependency diagram (MDD) An arrow in a module dependency diagram (MDD) indicates depends on or knows about Simplistically: Any name mentioned in the source code Main Main class depends on Timer Timer TimeToStretch Timer depends on TimeToStretch What is wrong with this design? Does Timer really need to depend on TimeToStretch? Is Timer re-usable in a new context?

Decoupling Timer needs to call the run method Timer does not need to know what the run method does Weaken the dependency of Timer on TimeToStretch Introduce a weaker specification, in the form of an interface or abstract class public abstract class TimerTask { public abstract void run(); Timer uses TimerTask, works with anything that meets the TimerTask specification (e.g., TimeToStretch)

TimeToStretch (version 2) public class TimeToStretch extends TimerTask { @Override public void run() { System.out.println("Stop typing!"); suggestexercise(); public void suggestexercise() {...

Timer (version 2) public class Timer { private TimerTask task; public Timer(TimerTask task) { this.task = task; public void start() { while (true) {... task.run(); Main creates the TimeToStretch object and passes it to Timer: Timer t = new Timer(new TimeToStretch()); t.start();

Module dependency diagram (version 2) Main TimerTask Timer Dependence Subclassing TimeToStretch Timer depends on TimerTask, not TimeToStretch Unaffected by implementation details of TimeToStretch Now Timer is much easier to reuse Main depends on the constructor for TimeToStretch Main still depends on Timer. Is this necessary?

The callback design pattern A computes A calls B B computes Before B completes, B calls A A computes A returns a value B computes more B returns A computes more Example: Factory object Advantage: B does not depend on A B depends on some superclass of A A synchronous callback. Time increases downward. Solid lines: calls Dotted lines: returns It s a callback whenever the stack contains: my code library code my code even if the two my code are not the same object or class

Examples of callbacks Synchronous callbacks: Examples: HashMap calls its client s hashcode, equals Useful when the callback result is needed immediately by the library Asynchronous callbacks: Examples: GUI listeners Register to indicate interest and where to call back A synchronous callback. Time increases downward. Solid lines: calls Dotted lines: returns Useful when the callback should be performed later, when some interesting event occurs

Use a callback to invert a dependency Main Main TimeToStretch Timer Dependence Subclassing TimerTask TimeToStretch Timer New design: TimeToStretch creates a Timer, and passes in a reference to itself so the Timer can call it back Main Benefit: Main does not depend on Timer TimerTask Timer TimeToStretch Inverted dependency, compared to version 1

TimeToStretch (version 3) public class TimeToStretch extends TimerTask { private Timer timer; public TimeToStretch() { timer = new Timer(this); public void start() { timer.start(); @Override public void run() { Callback entry point Register interest with the timer System.out.println("Stop typing!"); suggestexercise();...

Main (version 3) TimeToStretch tts = new TimeToStretch(); tts.start(); Main Main does not depend on Timer TimeToStretch depends on Timer TimerTask Timer TimeToStretch

Decoupling and design A good design has dependences (coupling) only where it makes sense While you design (before you code), examine dependences Don t introduce unnecessary coupling Coupling is an easy temptation if you code first Suppose a method needs information from another object If you hack in a way to get it: The hack might be easy to write It will damage the code s modularity and reusability More complex code is harder to understand

Design exercise #2 A program to display information about stocks stock tickers spreadsheets graphs Naive design: Make a class to represent stock information That class updates all views of that information (tickers, graphs, etc.) when it changes

Module dependency diagram Main class gathers information and stores in Stocks Stocks class updates viewers when necessary Main Stocks StockTicker Spreadsheet StockGraph Problem: To add/change a viewer, must change Stocks It is better to insulate Stocks from the vagaries of the viewers

Weaken the coupling What should Stocks class know about viewers? Stocks needs to call viewers update method when price changes Old: New (uses observer pattern ): void updateviewers() { myticker.update(newprice); myspreadsheet.update(newprice); mygraph.update(newprice); // Edit this method whenever // different viewers are desired. Callback How are observers created and registered? class Stocks { List<PriceObserver> observers; void notifyobserver() { for (PriceObserver obs : observers) { obs.update(newprice); interface PriceObserver { void update(...);

The observer pattern Stocks are not responsible for viewer creation Main passes viewers to Stocks as observers Stocks keeps list of observers, notifies them of changes Create Stocks and register observers Main Create viewers and get observers Observer Stocks Create (or be) observers StockTicker Spreadsheet StockGraph Issue: what info should update pass to unknown viewers?

A different design: pull versus push The Observer pattern implements push functionality A pull model: give viewers access to Stocks, let them extract the data they need Main new Viewer(Stocks) new Stocks() Stocks StockTicker Spreadsheet StockGraph The most efficient design (push or pull) depends on frequency of operations. (It's possible to use both patterns simultaneously.)

Another example of Observer pattern // Represents a sign-up sheet of students public class SignupSheet extends Observable { private List<String> students = new ArrayList<String>(); public void addstudent(string student) { students.add(student); notifyobservers(); public int size() { return students.size(); Inherited from Observable class Part of the JDK

An Observer public class SignupObserver implements Observer { // callback that should be called whenever the // observed object changes, to notify this observer public void update(observable o, Object arg) { Part of the JDK System.out.println("Signup count: " Not relevant to us + ((SignupSheet)o).size()); cast because Observable is not generic

Using the observer SignupSheet s = new SignupSheet(); s.addstudent("billg"); // nothing visible happens s.addobserver(new SignupObserver()); s.addstudent("torvalds"); // now text appears: "Signup count: 2" Java's Listeners (particularly in GUI classes) are examples of the Observer pattern You may use Java observer classes in your designs, but you are not required to do so.

User interfaces: appearance vs. content It is easy to tangle up appearance and content Particularly when supporting direct manipulation (e.g., dragging line endpoints in a drawing program) Another example: program state stored in widgets in dialog boxes Neither can be understood easily or changed easily This destroys modularity and reusability Over time, it leads to bizarre hacks and huge complexity Code must be discarded Callbacks, listeners, and other patterns can help

Shared constraints Coupling can result from shared constraints, not just code dependencies A module that writes a file and a module that reads the file depend on a common file format Even if there is no dependency on each other's code If one fails to write the correct format, the other will fail to read Shared constraints are easier to reason about if they are well encapsulated A single module should contain and hide all information about the format

Facade Want to perform secure file copies to a server Given a general purpose library, powerful and complex Good idea: build a facade a new interface to that library that hides its (mostly irrelevant) complexity ProxyHTTP Channel Session ChannelTCPIP ChannelTCPIP PortWatcher UserAuth Identity Packet UserInfo KeyPair HostKeys

Facade If the library changes, you can update only SecureCopy Backup MainDatabase ModManager SecureCopy ProxyHTTP Channel Session ChannelTCPIP ChannelTCPIP PortWatcher UserAuth Identity Packet UserInfo KeyPair HostKeys