l03 design patterns

79
Lecture 03 Design Patterns

Upload: olafur-andri-ragnarsson

Post on 28-Jan-2015

147 views

Category:

Education


0 download

DESCRIPTION

Design patterns are known and tested solutions to common problem. In software engineering we constantly come across similar problems. The same problems or tasks need to be programmed again and again, hence patterns. Design patterns catalog and document these solutions.They are built on industry knowledge of what works and why. We will look at what design patterns are, their history and the structure of documenting patterns. As an example we look at the Observer pattern. We will also look at Liskov Substitution Principle and the Open Close Principle, both which are very useful in building enterprise systems. Finally we look at creating objects.

TRANSCRIPT

Page 1: L03 Design Patterns

Lecture 03Design Patterns

Page 2: L03 Design Patterns

Agenda Patterns

– History, classification, structure Patterns covered

– Observer Design Principles

– Loosley Coupled Design Principle– Open-Close Principle– Liskov Substitution Principle

Page 3: L03 Design Patterns

Reading Fowler Introduction

– Section on Patterns, page 9-11 Design Patterns Observer pattern Factory pattern The Liskov Substitution Principle The Open-Closed Principle

Page 4: L03 Design Patterns

Pattern Catalog Catalog of Patterns of Enterprise

Application Architecture – Patterns in PoEAA– http://www.martinfowler.com/eaaCatalog/

Page 5: L03 Design Patterns

Patterns

Page 6: L03 Design Patterns

Design Patterns Design pattern is a general solution to a

common problem in software design– Systematic approach for problems that reoccur in

software development– Not complete solution but starting point for design – Not code ready to use– Patterns have names and definitions– Built on common practices

Patterns should not be language dependant– However patterns apply for types of programming

languages

Page 7: L03 Design Patterns

History Patterns originated as an architectural

concept“Each pattern describes a problem which occurs over and over again in our environment, and then describes the core of the solution to that problem, in such a way that you can use this solution a million times over, without ever doing it the same way twice”

- Christopher Alexander

Page 8: L03 Design Patterns

History Landmark book from 1995:Design

Patterns: Elements of Reusable Object-Oriented Software– Gang of Four (GoF)– Term Design Pattern is

borrowed from theconstruction industry

Several books on patternshave been published since– Head First Design Patterns

for example

Page 9: L03 Design Patterns

Vintage Design Patterns Design Patterns are like good red wine

– You cannot appreciate them at first– As you study them you learn the

difference between plonk and vintage,or bad and good designs

– As you become a connoisseur you experience the various textures you didn’t notice before

Warning:– Once you are hooked, you will no longer be

satisfied with inferior designsDr. Heinz Kabutz (http://www.javaspecialists.co.za)

Page 10: L03 Design Patterns

Pattern Classification Design patterns can be classified based on

multiple criteria– Basic underlying problem they solve

Classification– Fundamental patterns – Creational patterns – Structural patterns – Behavioral patterns – Concurrency patterns

Page 11: L03 Design Patterns

Enterprise Patterns Classification Domain Logic Patterns Data Source Architectural Patterns Object-Relational Behavioral Patterns Object-Relational Structural Patterns Object-Relational Metadata Mapping Patterns Web Presentation Patterns Distribution Patterns Offline Concurrency Patterns Session State Patterns Base Patterns

Page 12: L03 Design Patterns

Which of these statements is not true

A) Design Patterns are based on solutions from practiceB) Design Patterns are ideas not codeC) Design Patterns are based on specific programming languagesD) Design Patterns can have ambiguous names

QUIZ

Page 13: L03 Design Patterns

Structure of Patterns

Page 14: L03 Design Patterns

Structure of Patterns Name The Intent The Sketch Motivation How it Works When to Use it Further Reading Examples

Page 15: L03 Design Patterns

The Name Pattern names are important

– Need to create a vocabulary– Need to describe the pattern well– Avoid ambiguity and misunderstanding

Problems with names– Authors are using different names for same

pattern • Data Access Object and Table Data Gateway• Dependency Injection and Inversion of Control

– Authors are using same name for different patterns

• Example: Value Object is used for two similar patterns

Page 16: L03 Design Patterns

The Intent Sums up the pattern in a sentence or two

– Value Object:

A small simple object, like money or date range, whose equality isn’t based on identity

Page 17: L03 Design Patterns

The Sketch Visual representation of the pattern, often

but not always a UML diagram

Page 18: L03 Design Patterns

Motivation Description of a motivating problem for

the pattern– Problem description– May not be the only problem for the pattern

Example: – Layered supertype

It’s not uncommon for all the objects in a layer to have methods you don’t want to have duplicated throughout the system. You can move this behavior into a common Layer Supertype

Page 19: L03 Design Patterns

How it Works Describes the solution

– Implementation Issues– Variations– Independent of any particular platform– Platform dependent sections are identified– UML Diagrams if applicable

Plugin example

Page 20: L03 Design Patterns

When to Use It Describes when the pattern should be

used– Trade-offs– Comparisons

Layered Supertype example– Use Layer Supertype when you have common

features from all objects in a layer

Page 21: L03 Design Patterns

Examples Example code in Java or C#

– Layer Supertype Not working code

– pseudo code to give idea

class DomainObject...

private Long ID; public Long getID() { return ID; } public void setID(Long ID) { this.ID = ID; } public DomainObject(Long ID) { this.ID = ID; }

Page 22: L03 Design Patterns

Using Design Patterns How to use design patterns?

– Problem is the patterns can be complex and detailed

– Usually they are generic and abstract Ways to study patterns

– Implement them in test code– Sketch a class diagram in your context to see

the class dependencies– Form a “Study group” to discuss the patterns– Learn the vocabulary– Practice, practice, practice

Page 23: L03 Design Patterns

Problems with Patterns Ambiguity in Vocabulary

– Same pattern has different names– Different Patterns have same name

Appling the wrong pattern– Over-designing the solution– Patterns design for one language might not be

needed in another Not solving the original problem

– Using Remote Façade instead of avoiding network latencies

– Using EJB Entity Beans

Page 24: L03 Design Patterns

Job interview question

You are given the assignment of creating a component that needs to know sales statistics of Lottery tickets. You know that there is a another component in the system, Sale Server, that handles the sale. You need real-time information. What would you suggest?

EXERCISE

Page 25: L03 Design Patterns

Sale server Bingo

First proposal: Sale Server will call Bingo

Problem is that the Sale Server developer refuses to make a call to a specific game. His argument is that Sale Server should be for sale, and not be cluttered with game specific code.

Another solution is needed.

Page 26: L03 Design Patterns
Page 27: L03 Design Patterns

Sale server Bingo

registerObserver

notify

Page 28: L03 Design Patterns

The Observer Pattern

Page 29: L03 Design Patterns

The Weather Monitoring Example The Weather Monitoring application

Page 30: L03 Design Patterns

The Weather Monitoring Example Task

– We need to implement measurementsChanged so that it updates three different displays for current conditions, weather stats, and forcasts

– measurementsChanged is called any time data changes, we don’t know or care how this method is called

– Three display types must be updated– The system must be expandable – new display

types will be added

Page 31: L03 Design Patterns

The Weather Monitoring Example WeatherData class

public class WeatherData{ // instance variable declarations

public void measurementsChanged() { float temp = getTemperature(); float humidity = getHumidity(); float pressure = getPressure();

currentConditionsDisplay.update (temp, humidity, pressure); statisticsDisplay.update (temp, humidity, pressure); forcastConditionsDisplay.update (temp, humidity, pressure); } ...}

Page 32: L03 Design Patterns

Quiz Based on our first implementation, which of the

following apply

A. We are coding to concrete implementation not abstractions

B. For every new display element we need to alter codeC. We have no way to add (or remove) display elements at

runtimeD. The display elements don’t implement a common

interfaceE. We have not encapsulated the part that changesF. We are violating encapsulation of the WeatherData class

Page 33: L03 Design Patterns

The Weather Monitoring Example WeatherData class

public class WeatherData{ // instance variable declarations

public void measurementsChanged() { float temp = getTemperature(); float humidity = getHumidity(); float pressure = getPressure();

currentConditionsDisplay.update (temp, humidity, pressure); statisticsDisplay.update (temp, humidity, pressure); forcastConditionsDisplay.update (temp, humidity, pressure); } ...}

By coding to concreate implementation we have no way to add or remove displays without code change

Interface is that same for all

Page 34: L03 Design Patterns

ObserverOne or more observers or listeners are registered

to observe an event which may be raised by the observed object (the subject)

Sometimes called publish/subscribe– Similar to call-back handlers– One-to-Many relationship

Benefits– Listening object gets information when needed– Subject does not become dependent on multiple

observers

Page 35: L03 Design Patterns

Observer Design Pattern

Page 36: L03 Design Patterns

Observer Design Pattern Subject does not depend on listeners

Page 37: L03 Design Patterns

Loose Coupling When two object are loosley coupled, the can

interact but they have very little knowledge of each other

The Observer Pattern loosley coupled design– The only thing the subject knows about observer is

that it implements a ceratain interface– We can add new observers at any time– We never need to modify the subject to add new types

of observers– We can reuse subjects or observers independent of

each other

Page 38: L03 Design Patterns

Loosley Coupled Principle

Strive for loosely coupled designs between objects that interact

Page 39: L03 Design Patterns

Weather Station Examplepublic interface Subject{ public void registerObserver(Observer o); public void removeObserver(Observer o); public void notifyObservers();}

public interface DisplayElement{ public void display();}

public interface Observer{ public void update(float temp, float humidity, float pressure);}

Page 40: L03 Design Patterns

Weather Station Examplepublic class WeatherData implements Subject{ private ArrayList observers; private float temperature, humidity, pressure; public WeatherData() { observers = new ArrayList(); } public void registerObserver(Observer o) { observers.add(o); } public void removeObserver(Observer o) { int i = observers.indexOf(o); if (i>= 0) observers.remove(i); }

POLYMORPISHM

Page 41: L03 Design Patterns

Weather Station Example public void notifyObservers() { for (int i = 0; i<observers.size(); i++) { Observer observer = (Observer)observers.get(i); observer.update(temperature, humidity, pressure); } } public void measurementsChanged() { notifyObservers(); } // Test code public void setMeasurement(float temperature, float humidity, float pressure) { this.temperature = temperature; this.humidity = humidity; this.pressure = pressure; this.measurementsChanged(); }

POLYMORPISHM

Page 42: L03 Design Patterns

Weather Station Examplepublic class CurrentConditionsDisplay implements Observer, DisplayElement{ private float temperature, humidity; private Subject weatherData; public CurrentConditionsDisplay(Subject weatherData) { this.weatherData = weatherData; weatherData.registerObserver(this); } public void update(float temp, float humidity, float pressure) { this.temperature = temp; this.humidity = humidity; display(); } public void display() { System.out.println("Current conditions: " + temperature + "C " + "Humidity: " + humidity + "%"); }}

Registeringthis as an observer

The subject will call update

Page 43: L03 Design Patterns

Weather Station Examplepublic class WeatherStation{ public static void main(String[] args) { WeatherData weatherData = new WeatherData();

CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay(weatherData);

weatherData.setMeasurement(15, 50, 30); }}

Current conditions: 15.0C Humidity: 50.0%

Page 44: L03 Design Patterns

Loose Coupling When two object are loosley coupled, the can

interact but they have very little knowledge of each other

The Observer Pattern loosley coupled design– The only thing the subject knows about observer is

that it implements a ceratain interface– We can add new observers at any time– We never need to modify the subject to add new types

of observers– We can reuse subjects or observers independent of

each other

Page 45: L03 Design Patterns

Loosley Coupled Principle

Strive for loosely coupled designs between objects that interact

Page 46: L03 Design Patterns

Liskov Substitution Principle

Page 47: L03 Design Patterns

Overriding Behavior RubberDuck overwrote fly to do nothing

– Any use of Duck that expects fly behavior will not work correctly

– Users of the base class (Duck) should expect same functionality

– Violation of the Liskov Substitution Principle

Page 48: L03 Design Patterns

The Liskov Substitution Principle

Subtypes must be substitutable for their base types. Code that uses references to base class must be able to use objects of derived classes without knowing it.

BarbaraLiskov

Page 49: L03 Design Patterns

The Liskov Substitution Principle All code operating with reference to the

base class should be completely transparent to the type of the inherited object

It should be possible to substitute an object of one type with another within the same class hierarchy

Inheriting classes should not perform any actions that will invalidate the assumptions made by the base class

Page 50: L03 Design Patterns

LSP Examplepublic class Rectangle {

protected int _width; protected int _height; public int getWidth() { return _width; } public int getHeight() { return _height; } public void setWidth(int width) { _width = width; } public void setHeight(int height) { _height = height; }}

Page 51: L03 Design Patterns

LSP Examplepublic class Square extends Rectangle {

public void setWidth(int width) { _width = width; _height = width; }

public void setHeight(int height) { _height = height; _width = _height; } }

Implementation convenience

Page 52: L03 Design Patterns

LSP Exampleimport junit.framework.Assert;import org.junit.Test;

public class RectangleTests {

@Test public void areaOfRectangle() {

Rectangle r = new Square(); r.setWidth(5); r.setHeight(2); // Will Fail - r is a square and sets // width and height equal to each other. Assert.assertEquals(r.getWidth() * r.getHeight(),10); }}

Page 53: L03 Design Patterns

The Open-Closed Principle

Page 54: L03 Design Patterns

The Open-Closed Principle

Software entities like classes, modules and functions should be open for extension but closed for modifications

Page 55: L03 Design Patterns

The Open-Closed Principle Design and write code in a fashion that

adding new functionality would involve minimal changes to existing code– Most changes will be handled as new methods

and new classes– Designs following this principle would result in

resilient code which does not break on addition of new functionality

Page 56: L03 Design Patterns

public class ResourceAllocator{ ... public int allocate(intresourceType) { intresourceId; switch (resourceType) { case TIME_SLOT: resourceId = findFreeTimeSlot(); markTimeslotBusy(resourceId); break; case SPACE_SLOT: resourceId = findFreeSpaceSlot(); markSpaceSlotBusy(resourceId); break; ... } return resourceId; }...

Resource Allocator Example

Holy Buckets!!I need to change the class for new types!!! Horrible!

Page 57: L03 Design Patterns

Resource Allocator Example Design for extensions

List resources = new ArrayList();...public int allocate(intresourceType){ int resourceId = findFreeResource(resourceType); markAsBusy(resourceId); return resourceId;}

Page 58: L03 Design Patterns

Another Exampleprotected String normalize(char cCharacter) { switch(cCharacter) { case '<': return "&lt;"; case '>': return "&gt;"; case '&’: return "&amp;"; case '"’: return "&quot;"; default: return ""+cCharacter;} }

This is not complete This is common problem – a library must

exists If making it yourself, a Map would be

better

What is wrong withthis code?

Page 59: L03 Design Patterns

Creating Objects Revisted

Page 60: L03 Design Patterns

TaskWe need to create program that reads feedsFeed can be RSS news, XML or what ever

The program must be loosely coupledNew feed types will come

Page 61: L03 Design Patterns

Creating Objects Where does the creation take place?

Enterprise Application

This stays the sameThis that is added

Page 62: L03 Design Patterns

Call-back Handlers Inverting the Dependency

– Let a class call you back

Example– sort routine, reading records

ReaderProcess RssFeedReader

processEntryprocessEntryprocessEntry

Read

Page 63: L03 Design Patterns

Example: Reading RSS Process to read an RSS feed

– The FeedReader define the role of such readers

– Concrete readers must implement read and accept a call-back handler to get the results back

public interface FeedReader{ public boolean read(); public void setFeedHandler(FeedHandler handler);}

public interface FeedHandler{ public void processEntry(FeedEntry entry);}

Page 64: L03 Design Patterns

Example: Reading RSS AbstractFeedReader acts as a

superclass for concrete reader classes – Layered Supertype pattern

public abstract class AbstractFeedReader implements FeedReader{ protected FeedHandler feedHandler; public void setFeedHandler(FeedHandler handler) { this.feedHandler = handler; } public abstract boolean read();}

Page 65: L03 Design Patterns

Example: Reading RSS RssFeedReaderpublic class RssFeedReader extends AbstractFeedReader{ private String source;

public RssFeedReader(String source) { this.source = source; }

public boolean read() { // reading ... feedHandler.processEntry(new FeedEntry(ent.getTitle(), ent.getLink(), ent.getPublishedDate().toString())); } return true; }}

Page 66: L03 Design Patterns

Example: Reading RSS ReaderProcess is the clientpublic class ReaderProcess implements FeedHandler{ FeedReader reader;

public ReaderProcess() { ReaderFactory factory = ReaderFactory.getReaderFactory(); reader = factory.getFeedReader("http://..."); reader.setFeedHandler(this); }

public void processEntry(FeedEntry entry) { ... }}

Page 67: L03 Design Patterns

Example: Reading RSS

Page 68: L03 Design Patterns

Call-back Handlers Inverting the Dependency

– Let a class call you back

Example– sort routine, reading records

ReaderProcess RssFeedReader

processEntryprocessEntryprocessEntry

Read

Page 69: L03 Design Patterns

Creating objects Program to an implementation

Program to interface/subtype

Program to unknown creation

Dog d = new Dog();d.bark();

Animal animal = new Dog();animal.makeSound();

Animal animal = getAnimal();animal.makeSound();

Code smell!

Page 70: L03 Design Patterns

The Problem with “new” new is used to create object Problem is this:

– Even if we use supertypes (interfaces or abstract classes) we have to have concrete class behind it

– This violates the Program to Interfaces Design Principle

– The code also violates the Open Closed Principle

Animal animal = new Dog();animal.makeSound();

Page 71: L03 Design Patterns

Program to an interfacesDependency Injection– Make the caller responsible for setting the

dependencyprivate Animal animal;

public setAnimal(Animal animal){ this.animal = animal;}...

animal.makeSound();

Injection happens here,

in the set-method

LOOSE COUPLING = BEAUTIFUL!

Page 72: L03 Design Patterns

Program to unknown creation What does this mean?

Animal animal = getAnimal();animal.makeSound();

Where is this getAnimal

coming from?

Page 73: L03 Design Patterns

Factory

Page 74: L03 Design Patterns

FeedReader Objects are created with new

public class ReaderProcess { FeedReader reader;

public ReaderProcess() { reader = new RssFeedReader ("http://www.mbl.is/mm/rss/togt.xml");}

Holy Cow! new creates concrete object not abstraction!!

Page 75: L03 Design Patterns

FeedReader We need to have diffrent types

public ReaderProcess(String type, String source){ if(type.equals("rss")) reader = new RssFeedReader(source); else if (type.equals("atom")) reader = new AtomFeedReader(source); else if (type.equals("xml")) reader = new XmlFeedReader(source); reader.setFeedHandler(this);}

Holy Macaroni!This smells!!!Violates the OCP

Page 76: L03 Design Patterns

Moving the Dependency The name of the class is put in to a

properties file– ReaderFactory has no clue of what class it is– It just has to be a subclass of FeedReader public static FeedReader getFeedReader()

{ FeedProperties prop = new FeedProperties(); Class instanceClass; FeedReader reader = null; try { instanceClass = Class.forName(prop.getProperty("reader")); reader = (FeedReader)instanceClass.newInstance(); } catch (Exception e) { System.out.println("loading class failed"); return null; } reader.setSource(prop.getSource()); return reader; }

Page 77: L03 Design Patterns

Loading Properties Properties class

public class FeedProperties extends Properties{ protected String reader; protected String source; protected String DEFAULT_PROPERTIES = "feeds.properties";

public FeedProperties() { try { load(new FileInputStream(new File(DEFAULT_PROPERTIES))); reader = getProperty("reader"); source = getProperty("source"); } catch (Exception e) { System.out.println("Loading properties failed"); } }

feeds.propertiesreader=is.ru.honn.feeds.rss.RssFeedReadersource=http://www.mbl.is/mm/rss/togt.xml

Page 78: L03 Design Patterns

Summary Patterns are lessons from practice

– History, classification, structure Observer Pattern is useful for loose

coupling Design Principles

– Loosley Coupled Principle– Open-Close Principle– Liskov Substitution Principle

Page 79: L03 Design Patterns

Next Base Patterns Read Fowler chapter 18