Module dependences and decoupling CSE 331 University of Washington.

Slides:



Advertisements
Similar presentations
Design Validation CSCI 5801: Software Engineering.
Advertisements

Multi-threaded applications SE SE-2811 Dr. Mark L. Hornick 2 What SE1011 students are told… When the main() method is called, the instructions.
UMBC Some Additional Patterns CMSC 432. UMBC More Patterns2 Introduction Over the next few lectures we’ll have an introduction to a number of patterns.
Observer Method 1. References Gamma Erich, Helm Richard, “Design Patterns: Elements of Reusable Object- Oriented Software” 2.
OOP Design Patterns Chapters Design Patterns The main idea behind design patterns is to extract the high level interactions between objects and.
A Behavioral Pattern. Problem: Simple enough right? Object.
Liang, Introduction to Java Programming, Eighth Edition, (c) 2011 Pearson Education, Inc. All rights reserved Immutable Objects and Classes.
Reza Gorgan Mohammadi AmirKabir University of Technology, Department of Computer Engineering & Information Technology Advanced design.
Inheritance. Extending Classes It’s possible to create a class by using another as a starting point  i.e. Start with the original class then add methods,
System Architecture Lecture 3 CSE 111 Spring /22/20151Copyright William E. Howden.
Aalborg Media Lab 23-Jun-15 Inheritance Lecture 10 Chapter 8.
Cosc 4755 Phone programming: GUI Concepts & Threads.
Façade Design Pattern Source: Design Patterns – Elements of Reusable Object- Oriented Software; Gamma, et. al.
Threads II. Review A thread is a single flow of control through a program Java is multithreaded—several threads may be executing “simultaneously” If you.
Object-Oriented Analysis and Design
Chapter 7 Designing Classes. Class Design When we are developing a piece of software, we want to design the software We don’t want to just sit down and.
REFACTORING Lecture 4. Definition Refactoring is a process of changing the internal structure of the program, not affecting its external behavior and.
Chapter 3 Introduction to Collections – Stacks Modified
Observer Design Pattern Source: Design Patterns – Elements of Reusable Object- Oriented Software; Gamma, et. al.
Implementing Design Patterns Using Java St. Louis Java Special Interest Group Eric M. Burke Object Computing, Inc. Presented on July 9, 1998 (updated July.
CSC 313 – Advanced Programming Topics. Observer Pattern Intent  Efficiently perform 1-to-many communication  Easy to respond dynamically when event(s)
CSE 331 Software Design & Implementation Dan Grossman Winter 2014 Events, Listeners, and Callbacks (Based on slides by Mike Ernst, David Notkin, Hal Perkins)
CSE 331 SOFTWARE DESIGN & IMPLEMENTATION MODULAR DESIGN PRINCIPLES Autumn 2011 Google image search on “designing software modules”
Design Patterns Part two. Structural Patterns Concerned with how classes and objects are composed to form larger structures Concerned with how classes.
Features of Object Oriented Programming Lec.4. ABSTRACTION AND ENCAPSULATION Computer programs can be very complex, perhaps the most complicated artifact.
Chapter 26 GoF Design Patterns. The Adapter Design Pattern.
REVIEW On Friday we explored Client-Server Applications with Sockets. Servers must create a ServerSocket object on a specific Port #. They then can wait.
Observer Behavioral Pattern. Intent Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified.
(c) University of Washington08-1 CSC 143 Models and Views Reading: Ch. 18.
CSE 331 SOFTWARE DESIGN & IMPLEMENTATION MIDTERM REVIEW Autumn 2011.
Liang, Introduction to Java Programming, Sixth Edition, (c) 2005 Pearson Education, Inc. All rights reserved Chapter 27 JavaBeans and.
Sadegh Aliakbary. Copyright ©2014 JAVACUP.IRJAVACUP.IR All rights reserved. Redistribution of JAVACUP contents is not prohibited if JAVACUP.
CSE 332: Design Patterns Review: Design Pattern Structure A design pattern has a name –So when someone says “Adapter” you know what they mean –So you can.
Final Review. From ArrayLists to Arrays The ArrayList : used to organize a list of objects –It is a class in the Java API –the ArrayList class uses an.
Object-Oriented Software Engineering Practical Software Development using UML and Java Chapter 6: Using Design Patterns.
Design Patterns Software Engineering CS 561. Last Time Introduced design patterns Abstraction-Occurrence General Hierarchy Player-Role.
Concordia University Department of Computer Science and Software Engineering Click to edit Master title style ADVANCED PROGRAMMING PRACTICES Model View.
(1) Introduction to Java GUIs Philip Johnson Collaborative Software Development Laboratory Information and Computer Sciences University of Hawaii Honolulu.
1 CSE 331 Model/View Separation and Observer Pattern slides created by Marty Stepp based on materials by M. Ernst, S. Reges, D. Notkin, R. Mercer, Wikipedia.
The Mediator Pattern (Behavioral) ©SoftMoore ConsultingSlide 1.
CSE 331 Software Design & Implementation Hal Perkins Winter 2013 Events, Listeners, and Callbacks (slides by Mike Ernst and David Notkin) 1.
1 COS 260 DAY 12 Tony Gauvin. 2 Agenda Questions? 5 th Mini quiz –Chapter 5 40 min Assignment 3 Due Assignment 4 will be posted later (next week) –If.
Session 7 Introduction to Inheritance. Accumulator Example a simple calculator app classes needed: –AdderApp - contains main –AddingFrame - GUI –CloseableFrame.
L10: Model-View-Controller General application structure. User Interface: Role, Requirements, Problems Design patterns: Model – View – Controller, Observer/Observable.
Slide design: Dr. Mark L. Hornick
COMPOSITE PATTERN NOTES. The Composite pattern l Intent Compose objects into tree structures to represent whole-part hierarchies. Composite lets clients.
Liang, Introduction to Java Programming, Eighth Edition, (c) 2011 Pearson Education, Inc. All rights reserved Fall 2013 Chapter 10 Thinking.
Java for android Development Nasrullah Khan. Using instanceof in Android Development the classes such as Button, TextView, and CheckBox, which represent.
Observer Pattern Context:
Chapter 10 Thinking in Objects
Mediator Design Pattern
Chapter 10 Thinking in Objects
Chapter 10 Thinking in Objects
Observer Design Pattern
Project Topic 2: Migration to Java 9
CSE 331 Software Design and Implementation
CSE 331 Software Design and Implementation
Design Patterns, cont..
Chapter 9 Thinking in Objects
CSE 331 Software Design and Implementation
CSE 143 Lecture 2 Collections and ArrayIntList
CSE 331 Software Design & Implementation
Chapter 9 Thinking in Objects
Constructors, GUI’s(Using Swing) and ActionListner
Advanced ProgramMING Practices
8. Observer Pattern SE2811 Software Component Design
Advanced ProgramMING Practices
Model, View, Controller design pattern
CSE 331 Software Design & Implementation
Software Design Lecture : 28.
Presentation transcript:

Module dependences and decoupling CSE 331 University of Washington

The limits of scaling What prevents us from operating huge, intricate structures that work perfectly and indefinitely? - No friction - No gravity - No wear-and-tear … the difficulty of understanding them

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 FINAL PROJECT An application MY FINAL PROJECT A poor decomposition (parts strongly coupled) MY FINECT PROJAL A better decomposition (parts weakly coupled)

Coupling is the path to the dark side Coupling leads to complexity Complexity leads to confusion Confusion leads to suffering Once you start down the dark path, forever will it dominate your destiny, consume you it will

Design exercise #1 Write a typing break reminder program Offer the hard-working user occasional reminders of the perils of Repetitive Strain Injury, and encourage the user to take a break from typing Naive design: - Make a method to display messages and offer exercises - Make a loop to call that method from time to time (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 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” Any name mentioned in the source code Main class depends on Timer Main 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 doesn't 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 only needs to know that something (e.g., TimeToStretch) meets the TimerTask specification

TimeToStretch (version 2) public class TimeToStretch extends TimerTask { 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 still depends on Timer (is this necessary?) Main depends on the constructor for TimeToStretch Timer depends on TimerTask, not TimeToStretch - Unaffected by implementation details of TimeToStretch - Now Timer is much easier to reuse Main TimerTaskTimer Dependence Subclassing TimeToStretch

The callback design pattern TimeToStretch creates a Timer, and passes in a reference to itself so the Timer can call it back - A callback is a method call from a library to a client e.g., notifies about some condition Use a callback to invert a dependency - Inverted dependency: TimeToStretch depends on Timer (not vice versa) - Side benefit: Main does not depend on Timer

Callbacks Synchronous callbacks: Examples: HashMap calls its client’s hashCode, equals Asynchronous callbacks: Examples: GUI listeners Register to indicate interest and where to call back Time increases downward Solid lines: calls Dotted lines: returns

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

Main (version 3) TimeToStretch tts = new TimeToStretch(); tts.start(); Use a callback to invert a dependency This MDD inverts the dependency between Timer and TimeToStretch (compared to ver. 1) 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 StocksStockTicker 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? Needs an update method to call when things change Old: void updateViewers() { myTicker.update(newPrice); mySpreadsheet.update(newPrice); myGraph.update(newPrice); // Edit this method whenever // different viewers are desired. } Callback New (uses “observer pattern”): List observers; void notifyObserver() { for (Observer obs : observers) { obs.update(newPrice); } interface Observer { void update(...); } How are observers created?

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 new() Main Stocks.new() Observer Stocks.register(Obs) Stocks StockTicker Spreadsheet StockGraph Problem: doesn't know what info each Observer needs

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 new(Stocks) Main Stocks.new Stocks StockTicker Spreadsheet StockGraph The best design depends on frequency of operations (It's also possible to use both patterns simultaneously.)

Another example of Observer pattern // Represents a sign-up sheet of students Part of the JDK public class SignupSheet extends Observable { private List students = new ArrayList (); public void addStudent(String student) { students.add(student); notifyObservers(); } public int size() { return students.size(); } }

An Observer Part of the JDK public class SignupObserver implements Observer { // called whenever the observed object is changed public void update(Observable o, Object arg) { System.out.println("Signup count: " Not relevant to us + ((SignupSheet)o).size()); } } cast because Observable is non-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

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 ProxyHTTPChannelSession ChannelTCPIP Identity PortWatcherUserAuth PacketUserInfoKeyPairHostKeys

Facade If the library changes, you can update only SecureCopy BackupMainDatabaseModManager SecureCopy ProxyHTTPChannelSession ChannelTCPIP Identity PortWatcherUserAuth PacketUserInfoKeyPairHostKeys