OODP Session 9. Session times PT Thursday 18:00 21:00 room: School of Pharmacy, John Hanbury Lecture Theatre FT Tuesday 13:30 17:00 room: Malet 404

Similar documents
Object Oriented. Analysis and Design

OODP OOAD Session 7a

Object Oriented Design and Programming Revision

OODP Session 5a. Web Page: Visiting Hours: Tuesday 17:00 to 19:00

OODP Session 4. Web Page: Visiting Hours: Tuesday 17:00 to 19:00

Introduction to Software Engineering: Tools and Environments. Session 5. Oded Lachish

Software Eningeering. Lecture 9 Design Patterns 2

Design Patterns Lecture 2

The Design Patterns Matrix From Analysis to Implementation

public class Account { private int id; private static int nextaccountid = 0; private String name; private double balance;

Chain of Responsibility

EXAMINATIONS 2012 END-OF-YEAR SWEN222. Software Design. Question Topic Marks 1. Design Quality Design Patterns Design by Contract 12

CS 215 Software Design Sample midterm solutions

Software Testing Prof. Meenakshi D Souza Department of Computer Science and Engineering International Institute of Information Technology, Bangalore

Component ConcreateComponent Decorator ConcreateDecoratorA ConcreteDecoratorB

Five EASY Steps to Switch to

Tecniche di Progettazione: Design Patterns

Introduction to Inheritance

Software Design and Analysis for Engineers

COMS W3101 Programming Language: C++ (Fall 2015) Ramana Isukapalli

Creating and Using Objects

Tecniche di Progettazione: Design Patterns

The Chain of Responsibility Pattern

The Chain of Responsibility Pattern. Design Patterns In Java Bob Tarr

In this Lecture you will Learn: Object Design. Information Sources for Object Design. Class Specification: Attributes

Tuesday, October 4. Announcements

Chapter 1: Programming Principles

The Object Class. java.lang.object. Important Methods In Object. Mark Allen Weiss Copyright 2000

Administrivia. IBM Info Session Date: Wed,, Jan 13 Time: 5:30 7 pm Location: Wesbrook 100

2/23/04 Doc 10 State & Chain of Responsibility slide # 1

Implementing a List in Java. CSE 143 Java. Just an Illusion? List Interface (review) Using an Array to Implement a List.

Design Patterns. Structural Patterns. Oliver Haase

» Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request!

Implementing a List in Java. CSC 143 Java. List Interface (review) Just an Illusion? Using an Array to Implement a List CSC

Cloning Enums. Cloning and Enums BIU OOP

Functional Programming, Classes, and Recursion!

Arrays and Array Lists

Quarter 1 Practice Exam

Chain of Responsibility Pattern*

The object-oriented approach goes a step further by providing tools for the programmer to represent elements in the problem space.

Implementing a List in Java. CSE 143 Java. List Interface (review) Just an Illusion? Using an Array to Implement a List.

Principles of Software Construction: Objects, Design, and Concurrency. Assigning Responsibilities to Objects. toad. Jonathan Aldrich Charlie Garrod

Abstract Classes and Interfaces

A Sophomoric Introduction to Shared-Memory Parallelism and Concurrency Lecture 4 Shared-Memory Concurrency & Mutual Exclusion

Credit where Credit is Due. Lecture 25: Refactoring. Goals for this lecture. Last Lecture

Introduction to Objects. James Brucker

CSCI-1200 Computer Science II Fall 2006 Lecture 23 C++ Inheritance and Polymorphism

The Object Recursion Pattern

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

Tecniche di Progettazione: Design Patterns

Design to interfaces. Favor composition over inheritance Find what varies and encapsulate it

CSE332: Data Abstractions Lecture 22: Shared-Memory Concurrency and Mutual Exclusion. Tyler Robison Summer 2010

Object-Oriented Design

CS61B Lecture #5: Arrays and Objects

UNIVERSITI SAINS MALAYSIA. CIT502 Object-Oriented Programming and Software Engineering

Software Engineering Prof. Rushikesh K.Joshi IIT Bombay Lecture-15 Design Patterns

1: Introduction to Object (1)

Solution register itself

Principles of Software Construction: Objects, Design, and Concurrency. Part 1: Designing Classes. Design for Reuse School of Computer Science

PRINCIPLES OF SOFTWARE BIM209DESIGN AND DEVELOPMENT 10. PUTTING IT ALL TOGETHER. Are we there yet?

CSE 70 Final Exam Fall 2009

CS61B Lecture #19. Last modified: Mon Oct 13 12:02: CS61B: Lecture #19 1

COURSE 2 DESIGN PATTERNS

Chapter 5: Arrays. Chapter 5. Arrays. Java Programming FROM THE BEGINNING. Copyright 2000 W. W. Norton & Company. All rights reserved.

Design Patterns. CSC207 Winter 2017

BM214E Object Oriented Programming Lecture 11

ITI Introduction to Computing II

ITI Introduction to Computing II

CSCI-1200 Data Structures Fall 2017 Lecture 25 C++ Inheritance and Polymorphism

BCS THE CHARTERED INSTITUTE FOR IT. BCS HIGHER EDUCATION QUALIFICATIONS BCS Level 5 Diploma in IT. Object Oriented Programming

CS112 Lecture: Defining Classes. 1. To describe the process of defining an instantiable class

Switchvox PBX User Manual

Design First ITS Instructor Tool

Design Patterns V Structural Design Patterns, 2

CS112 Lecture: Defining Instantiable Classes

Software Development

C Sc 335 Practice Test 2 Answers 1a) Create an initial list of classes that would do a good job of modeling this system (ANSWER MAY VARY)

Name: Checked: Objectives: Practice creating classes and methods, and using them in your programs.

CSCD01 Engineering Large Software Systems. Design Patterns. Joe Bettridge. Winter With thanks to Anya Tafliovich

CSCD01 Engineering Large Software Systems. Design Patterns. Joe Bettridge. Winter With thanks to Anya Tafliovich

Basic Object-Oriented Concepts. 5-Oct-17

Java Programming. Computer Science 112

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

MITOCW watch?v=flgjisf3l78

University of Massachusetts Amherst, Electrical and Computer Engineering

Advanced Programming - JAVA Lecture 4 OOP Concepts in JAVA PART II

CS61B Lecture #7. Announcements:

OBJECT-ORIENTED DOMAIN DRIVEN DESIGN. Robert Bräutigam MATHEMA So ware GmbH.

Chain of Responsibility

Lecture 7: Data Abstractions

BASIC COMPUTATION. public static void main(string [] args) Fundamentals of Computer Science I

A Reconnaissance on Design Patterns

index.pdf January 21,

Objectives. Problem Solving. Introduction. An overview of object-oriented concepts. Programming and programming languages An introduction to Java

CS32 Discussion Sec.on 1B Week 2. TA: Zhou Ren

Procedural Abstraction

EINDHOVEN UNIVERSITY OF TECHNOLOGY

Design Patterns 2. Page 1. Software Requirements and Design CITS 4401 Lecture 10. Proxy Pattern: Motivation. Proxy Pattern.

Design Patterns: Part 2

Announcements. Lecture 05a Header Classes. Midterm Format. Midterm Questions. More Midterm Stuff 9/19/17. Memory Management Strategy #0 (Review)

Transcription:

OODP Session 9 Session times PT Thursday 18:00 21:00 room: School of Pharmacy, John Hanbury Lecture Theatre FT Tuesday 13:30 17:00 room: Malet 404 1 Email: oded@dcs.bbk.ac.uk Web Page: http://www.dcs.bbk.ac.uk/~oded Visiting Hours: Tuesday 17:00 to 19:00

Chain of Responsibility Design pattern 2

Why do we need this pattern? We will start by trying to do without it. Clone the project from git://github.com/odedlac/bank.git This project contains raw code for automating a bank teller. 3

Bank Project The project contains raw code for automating a bank teller At this stage the teller can do only two things 1. Open an account 2. Withdraw money Technically what teller does is delegate the actual doing of the operations to two other classes. OpenAccountHandler Teller openaccount withdrawmoney openaccount WithdrawMoneyHandler 4 withdrawmoney

OpenAccountHandler The OpenAccountHandler simplycoordinates all the operations required for opening an account, as we shall see in the code at the next slide. OpenAccountHandler displaystring result Accounts doesaccountexist opennewaccount deposit getbalance withdraw Display BackgroundCheck openaccount 5

public Boolean openaccount(string string) { if(!backgroundcheck.result(string)){ display.displaystring("sorry request refused"); return false; Integer accountnumber = accounts.opennewaccount(); display.displaystring("request accepted. New account number is: " + accountnumber); return true; Background test hasn t failed. Account opened and customer informed through display. Runs a background check if it fails then it returns false since. 6

WithdrawMoneyHandler The WithdrawMoneyHandler simply coordinates all the operations required for withdrawing money. Accounts doesaccountexist opennewaccount deposit getbalance withdraw displaystring Display Money OpenAccountHandler givemoney openaccount 7

Bank Project Why would we need such a solution. One possible scenario: We created the teller class because of the controller grasp pattern But after some agile iterations it turns out that the variety and number of requests the teller has to handle is causing us Cohesion issues. Our solution delegate OpenAccountHandler Teller openaccount withdrawmoney openaccount WithdrawMoneyHandler 8 withdrawmoney

What is wrong with this solution In order to understand what is wrong with this solution lets add another possible handler to the teller. You have 15 minutes to write a fully supported depositmoneyhandler. It should be implemented on the same lines as the other Handlers. DepositMoneyHandler 9 Teller openaccount withdrawmoney depositmoneyaccount OpenAccountHandler openaccount WithdrawMoneyHandler withdrawmoney

Are you happy with this solution? Coupling we had to add methods to Teller and we don t want to do that because the number of such methods may be very large. Any idea how to solve this? 10

Idea 1. Create a request class that contains all the relevant information. 2. Use a myrequest object in order to tell the teller object what to do 3. The teller object will delegate it to each of the requesthandlers 4. A request handler should check whether he can handle the request and only then handle it MyRequest requesttype accountnumber name sum getrequesttype getname getaccountnumber getsum 11 Clone code from git://github.com/odedlac/bankwithrequests.git

Comparing new to old code (test1 in TellerTest) Old: public void test1() { assertfalse("opened account when shouldn't", classundertest.openaccount("oded")); New: public void test1() { MyRequest myrequest = new MyRequest("OpenAccount","Oded",0,0); assertfalse("opened account when shouldn't", classundertest.handlerequest(myrequest)); Adding MyRequest made dealing with the teller a bit more complicated 12

Comparing new to old code (changes to teller) Old: public boolean openaccount(string string) { return openaccounthandler.openaccount(string); public boolean withdraw(integer accounttested, Integer sumtested) { return withdrawmoneyhandler.withdraw(accounttested, sumtested); New: public boolean handlerequest(myrequest myrequest) { if(openaccounthandler.handlerequest(myrequest)){ return true; if(withdrawmoneyhandler.handlerequest(myrequest)){ return true; return false; 13 Adding MyRequest reduced number of methods in teller, and simplified the delegation

Comparing new to old code (changes to withdrawmoneyhandler) Old: public boolean withdraw(integer accountnumber, Integer sum) { New: private boolean withdraw(integer accountnumber, Integer sum) { public boolean handlerequest(myrequest myrequest) { // TODO Auto generated method stub if(myrequest.getrequesttype().equals("withdrawmoney")){ return withdraw(myrequest.getaccountnumber(),myrequest.getsum()); return false; 14 Adding forced adding a new method to handle myrequest (the withdraw method is now private)

Challenge You have 12 minutes to write a fully supported depositmoneyhandler. It should be implemented on the same lines as the other Handlers. Are you happy with this solution? Coupling we had to add code in Teller and we don t want to do that because the method may grow very large. Any idea how to solve this? 15

Lets apply The Chain of Responsibility Design Pattern

Chain of Responsibility Problem: How to handle a request when it is not known which object should deal with it? Motivation: In the example (with the GRASP pattern) we had a controller. What if in order to avoid cohesion we need many controllers, one for each complex operation On top of that we want to be able to add more operations 17

Chain of Responsibility successor client Handler handlerequest() ConcreteHandler1 handlerequest() ConcreteHandler2 handlerequest() 18

Pattern implementation 1. Clone the project from git://github.com/odedlac/bankwcor.git 19

Handler Code public abstract class Handler { protected Handler handler; public Handler() { this.handler = null; public void sethandler(handler handler){ this.handler = handler; public abstract Boolean handlerequest(myrequest myrequest); Straight forward implemntation handler is a reference to the next in line. By default it is nul. handlerequest method must be implemented since it is abstract 20

Comparing newer to new code New: TellerTest public void setup() throws Exception { Accounts accounts = new Accounts(); accounts.deposit(accounts.opennewaccount(), 100); accounts.deposit(accounts.opennewaccount(), 200); Money money = new Money(); Display display = new Display(); BackgroundCheck backgroundcheck = new BackgroundCheck(); WithdrawMoneyHandler withdrawmoneyrequest = new WithdrawMoneyHandler(accounts,money,display); OpenAccountHandler openaccountrequest = new OpenAccountHandler(accounts,backGroundCheck,display); classundertest = new Teller(openAccountRequest,withdrawMoneyRequest); Newer: ChainTest public void setup() throws Exception { Accounts accounts = new Accounts(); accounts.deposit(accounts.opennewaccount(), 100); accounts.deposit(accounts.opennewaccount(), 200); Money money = new Money(); Display display = new Display(); BackgroundCheck backgroundcheck = new BackgroundCheck(); Handler withdrawmoneyrequest = new WithdrawMoneyHandler(accounts,money,display); classundertest = new OpenAccountHandler(accounts,backGroundCheck,display); classundertest.sethandler(withdrawmoneyrequest); 21 Pattern made Teller redundant. Creation of Handlers is slightly harder.

Comparing newer to new code (WithdrawMoneyHandler) New: public boolean handlerequest(myrequest myrequest) { // TODO Auto generated method stub if(myrequest.getrequesttype().equals("withdrawmoney")){ return withdraw(myrequest.getaccountnumber(),myrequest.getsum()); return false; Newer: public Boolean handlerequest(myrequest myrequest) { if(myrequest.getrequesttype().equals("withdrawmoney")){ return withdraw(myrequest.getaccountnumber(),myrequest.getsum()); else if(super.handler == null){ return false; return super.handler.handlerequest(myrequest); Request handler slightly more complicated because of chain requirements 22

Pattern implementation 1. You have 10 minutes to write a fully supported depositmoneyhandler. It should be implemented on the same lines as the other Handlers. 2. Any idea of which other pattern maybe nice to have here. 3. If you have time to spare then maybe try to implement it 23

Chain of Responsibility, Pros and Cons Pro 1. Reduced coupling 2. Flexibility easy to add new handlers Cons 1. Need ensure the chain is created properly 2. Requests might not be handled 3. The request object may become too large 24

Observer

Auditor We want to simulate an auditor that wants to observe every single change in each account How would you design such a class What is the problem with this solution? What if there is more than one auditor and they may want to come and go? Auditor mood notify () Accounts 26

Auditor is an Observer Solution: teach them the subject observer relation AbstractSubject attach(abstractobserver) detach(abstractobserver) AbstractObserver update() notifyobservers() Call every observer on the list Accounts Auditor update() 27 Get mood (possibly also other stuff)

Observer Implementation 1. Clone the project from git://github.com/odedlac/bankwithauditors.git 28

AbstractSubject Code public class AbstractSubject { private Set<AbstractObserver> observers; protected AbstractSubject(){ observers = new HashSet<AbstractObserver>(); public void attach(abstractobserver abstractobserver){ observers.add(abstractobserver); public void detach(abstractobserver abstractobserver){ observers.remove(abstractobserver); protected void notifyobservers(){ java.util.iterator<abstractobserver> auditorsiterator = observers.iterator(); while(auditorsiterator.hasnext()) { auditorsiterator.next().update(); 29

AbstractObserver Code public abstract class AbstractObserver { abstract void update(); 30

Auditor Code public class Auditor extends AbstractObserver { private Accounts accounts; private Integer number; public Auditor(Accounts accounts,integer number) { this.accounts = accounts; this.number = number; /* (non Javadoc) * @see code.abstractobserver#update() */ @Override void update() { System.out.println(number + " Someone is messing with the accounts " + accounts.doesaccountexist(1)); 31

Changes to Accounts code public class Accounts extends AbstractSubject { public Integer opennewaccount() { super.notifyobservers(); Integer accountnumber = numbertobalance.size()+1; numbertobalance.put(accountnumber, 0); return accountnumber; 32

Auditors test code public class AuditorTest { Accounts accounts; AbstractObserver auditor1; AbstractObserver auditor2; @Before public void setup() throws Exception { accounts = new Accounts(); accounts.opennewaccount(); accounts.opennewaccount(); auditor1 = new Auditor(accounts,1); auditor2 = new Auditor(accounts,2); accounts.attach(auditor1); accounts.attach(auditor2); 33

Pattern implementation 1. You have 15 minutes to A. Add an observer to some other class B. Try to make the whole thing fail because of observer design pattern abuse 34

Discussion Why Use? A change to one object requires change to another object One object can notify others without any dependency on their class Issues Need some mechanism to say what changed Without maintenance, may get an unwanted cascade of updates 35

More Advanced Patterns Bridge

DriverAI Problem: We want to decouple an abstraction from its implementation AI swim () drive() travel() Why can t we settle for inheritance? SmartAI swim () drive() travel() BraveAI swim () drive() travel() 37

Bridge Pattern Solution: delegate implementation AI swim () drive() travel() ImpAI ImpAI swim () drive() Problem: there maybe different AI s, with added responsibilities ImpSmartAI ImpBraveAI 38 void AI::travel() { ImpAI->drive(); ImpAI->swim(); swim() drive() swim() drive()

Solution: Inheritance Abstraction Implementor Implementor operationalpha () operationbeta () impoperation1 () impoperation2 () AI AI ConcreteImplementorA ConcreteImplementorB operationalpha () operationbeta () operationgamma () operationalpha () operationbeta () operationdelta () impoperation1 () impoperation2 () impoperation1 () impoperation2 () 39

Discussion Why use? Avoiding permanent binding Abstraction and implementations are extensible by binding Implementation change have no impact on clients Implementation hidden Implementations can be shared (what is the difference from strategy) 40

Something to do at home 1. Do the first example from scratch with mock objects for classes such as Accounts etc. 2. Use a MyRequest mock object in the second example and write tests to check how it was treated 3. Like two but see if you can learn how to spy 4. Draw class UML diagrams for the examples 5. Apply other patterns to the examples (if you can find a good place to do so) 41