computer science 340 software design & testing...

29
1 Computer Science 340 Software Design & Testing Inheritance Template Method Pattern Factory Method Pattern

Upload: others

Post on 27-Jun-2020

2 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Computer Science 340 Software Design & Testing Inheritancecs340ta/winter2019/notes/rodham/43... · Template Method Pattern Factory Method Pattern. 2 Class Reuse •Two forms of class

1

Computer Science 340Software Design & Testing

Inheritance

Template Method PatternFactory Method Pattern

Page 2: Computer Science 340 Software Design & Testing Inheritancecs340ta/winter2019/notes/rodham/43... · Template Method Pattern Factory Method Pattern. 2 Class Reuse •Two forms of class

2

Class Reuse• Two forms of class reuse:

– Class implementation inheritance• “extends” in Java• Different than “implements”, which is “interface

inheritance”– Object composition

A

B

AB

Inheritance

Composition

Page 3: Computer Science 340 Software Design & Testing Inheritancecs340ta/winter2019/notes/rodham/43... · Template Method Pattern Factory Method Pattern. 2 Class Reuse •Two forms of class

3

Class Inheritance

• This class is like that class except for these differences …

– Specialize superclass behavior by overriding methods• Totally replace a superclass operation• Add pre/post processing before/after

superclass operation– Extend superclass by adding new

variables/operations

A

B

Page 4: Computer Science 340 Software Design & Testing Inheritancecs340ta/winter2019/notes/rodham/43... · Template Method Pattern Factory Method Pattern. 2 Class Reuse •Two forms of class

4

Class Inheritance

A

B

• Inheritance establishes a subtyping relationship between subclass and superclass, thus enabling polymorphism

– Polymorphism = Subtyping + Dynamic method binding

– Subclass instances may be used anywhere superclass instances are expected• Liskov Substitution Principle

Page 5: Computer Science 340 Software Design & Testing Inheritancecs340ta/winter2019/notes/rodham/43... · Template Method Pattern Factory Method Pattern. 2 Class Reuse •Two forms of class

5

Object Composition• Client class creates an internal instance of existing class

and invokes its functionality through regular method calls

• Generally results in looser coupling than the inheritance relationship– With inheritance, changes to A are more likely to break B than

with composition

• No subtyping relationship is established between the two classes, thus preventing polymorphism

• Extra levels of indirection in method calls can reduce efficiency, but this usually isn�t a problem

AB

Page 6: Computer Science 340 Software Design & Testing Inheritancecs340ta/winter2019/notes/rodham/43... · Template Method Pattern Factory Method Pattern. 2 Class Reuse •Two forms of class

6

Choosing Between Composition Inheritance

• What type of relationship is being modeled?– B “has-a” A => composition– B “uses” A => composition– B “is-a” A => inheritance

• Specialization

Page 7: Computer Science 340 Software Design & Testing Inheritancecs340ta/winter2019/notes/rodham/43... · Template Method Pattern Factory Method Pattern. 2 Class Reuse •Two forms of class

7

Choosing Between Composition and Inheritance

• �Favor object composition over class inheritance.� [Design Patterns, pg. 20]

• Composition is:– More flexible than inheritance

– Leads to lower coupling than inheritance– Allows control over which delegate

features are exposed, and what the API looks like

– Often more complex than inheritance

Page 8: Computer Science 340 Software Design & Testing Inheritancecs340ta/winter2019/notes/rodham/43... · Template Method Pattern Factory Method Pattern. 2 Class Reuse •Two forms of class

8

Choosing Between Composition and Inheritance

• Inheritance:– Supports polymorphism, while composition

does not– Is easier if you want to expose many of the

superclass� features• Although Intellij and Eclipse both have a handy �Generate Delegate Methods� option for exposing delegate features if you�re using composition

Page 9: Computer Science 340 Software Design & Testing Inheritancecs340ta/winter2019/notes/rodham/43... · Template Method Pattern Factory Method Pattern. 2 Class Reuse •Two forms of class

9

Dynamic Inheritance

• Dynamic inheritance is when you have objects that change class over time

• Dynamic inheritance can be implemented using a combination of composition and interface inheritance

Page 10: Computer Science 340 Software Design & Testing Inheritancecs340ta/winter2019/notes/rodham/43... · Template Method Pattern Factory Method Pattern. 2 Class Reuse •Two forms of class

10

Dynamic Inheritance

• Example: Vocations– This inheritance-based design is inflexible because once a

person has been created, their vocation cannot change

Person

Engineer Doctor Lawyer SalesPerson

Page 11: Computer Science 340 Software Design & Testing Inheritancecs340ta/winter2019/notes/rodham/43... · Template Method Pattern Factory Method Pattern. 2 Class Reuse •Two forms of class

11

Dynamic Inheritance• Example: Vocations

– This design uses a combination of composition (with delegation) and interface inheritance to allow a person’s vocation to change over their lifetime

<<Interface>>

IPerson

Engineer Doctor Lawyer SalesPerson

Person

<<Interface>>

IPerson

Page 12: Computer Science 340 Software Design & Testing Inheritancecs340ta/winter2019/notes/rodham/43... · Template Method Pattern Factory Method Pattern. 2 Class Reuse •Two forms of class

12

Dynamic Inheritance

• Another example of dynamic inheritance

Employee

CommissionedEmployee

SalariedEmployee

HourlyEmployee

<<Interface>>

IEmployee

HourlyEmployee

CommissionedEmployee

SalariedEmployee

Employee

<<Interface>>

IEmployee

Page 13: Computer Science 340 Software Design & Testing Inheritancecs340ta/winter2019/notes/rodham/43... · Template Method Pattern Factory Method Pattern. 2 Class Reuse •Two forms of class

13

Multiple Inheritance• Multiple inheritance is when an object is a member

of multiple classes at once

Instructor Student

PhdStudent

Page 14: Computer Science 340 Software Design & Testing Inheritancecs340ta/winter2019/notes/rodham/43... · Template Method Pattern Factory Method Pattern. 2 Class Reuse •Two forms of class

14

Multiple Inheritance

<<Interface>>

IInstructor

Instructor

PhdStudent

<<Interface>>

IInstructor

<<Interface>>

IStudent

Student

<<Interface>>

IStudent• What if you need multiple inheritance, but your programming language does not support it (like Java)?

• This design uses a combination of composition and interface inheritance to allow a PhdStudent to be both an Instructor and a Student

• PhdStudent delegates method calls to Instructor and Student

Page 15: Computer Science 340 Software Design & Testing Inheritancecs340ta/winter2019/notes/rodham/43... · Template Method Pattern Factory Method Pattern. 2 Class Reuse •Two forms of class

15

Multiple Inheritance• Hybrid approach

• Use implementation inheritance for one super-class, and interface inheritance + composition for the other super-classes

• Which one should I use for implementation inheritance? The one that most closely matches the ”is-a” rule.

PhdStudent

Student

<<Interface>>

IInstructor

Instructor

<<Interface>>

IInstructor

Page 16: Computer Science 340 Software Design & Testing Inheritancecs340ta/winter2019/notes/rodham/43... · Template Method Pattern Factory Method Pattern. 2 Class Reuse •Two forms of class

16

Inheritance-Based Reuse• Inheritance is a more tightly coupled relationship than composition

– Inheritance is sometimes called “white box reuse”, and composition is called “black box reuse”

• Unwise programmers, when they realize they need to subclass an existing class, make all the “private” features “protected”, make all the methods “virtual”, and say, “There, now it’s a base class!”.

• This approach results in extremely high coupling between a base class and its subclasses, and results in a fragile base class (i.e., a base class that is difficult to change without breaking its subclasses)

• To minimize coupling, the “subclass interface” between a base class and its subclasses should be carefully designed

• Information hiding is still a good practice, even between super- and sub-classes

Page 17: Computer Science 340 Software Design & Testing Inheritancecs340ta/winter2019/notes/rodham/43... · Template Method Pattern Factory Method Pattern. 2 Class Reuse •Two forms of class

17

Designing the Subclass Interface

• Subclasses need to:

– Access base class features in ways not available through the public interface

– Specialize base class behavior

Public Interface

Subclass Interface

Base Class

Sub Class

Client Client

Page 18: Computer Science 340 Software Design & Testing Inheritancecs340ta/winter2019/notes/rodham/43... · Template Method Pattern Factory Method Pattern. 2 Class Reuse •Two forms of class

18

Designing the Subclass Interface• Base classes should typically

keep their variables private, and provide protected methods that allow subclasses to access or modify their state only in necessary, controlled ways

• Make a variable protected only if there is a good reason to do so

Public Interface

Subclass Interface

Base Class

Sub Class

Client Client

Page 19: Computer Science 340 Software Design & Testing Inheritancecs340ta/winter2019/notes/rodham/43... · Template Method Pattern Factory Method Pattern. 2 Class Reuse •Two forms of class

19

Designing the Subclass Interface• Keep methods private when

subclasses don’t need to access or override them

• Base classes should define polymorphic methods for aspects of their behavior that subclasses can specialize

– Virtual methods in C++– All non-final methods in Java

• Make a method polymorphic only if you expect subclasses to specialize it

• Specifically prevent specialization of methods that subclasses should not override

– Non-virtual methods in C++– “final” methods in Java

Public Interface

Subclass Interface

Base Class

Sub Class

Client Client

Page 20: Computer Science 340 Software Design & Testing Inheritancecs340ta/winter2019/notes/rodham/43... · Template Method Pattern Factory Method Pattern. 2 Class Reuse •Two forms of class

20

Designing the Subclass Interface• Keeping the subclass interface

as simple as possible has two positive outcomes:

– There is more freedom to change the internal implementation of the base class without breaking subclasses (i.e., base classes are less fragile)

– It is easier for subclass authors to understand how to specialize the base class (i.e., they have less freedom, but more guidance)

Public Interface

Subclass Interface

Base Class

Sub Class

Client Client

Page 21: Computer Science 340 Software Design & Testing Inheritancecs340ta/winter2019/notes/rodham/43... · Template Method Pattern Factory Method Pattern. 2 Class Reuse •Two forms of class

21

Patterns for Designing the Subclass Interface

• Template Method pattern• Factory Method pattern

Page 22: Computer Science 340 Software Design & Testing Inheritancecs340ta/winter2019/notes/rodham/43... · Template Method Pattern Factory Method Pattern. 2 Class Reuse •Two forms of class

22

Template Method Pattern• Code that is duplicated in multiple places should be centralized

in one place (i.e., avoid duplication)– Composition: Put common code in a method on a class to which

multiple clients will delegate– Inheritance: Put the common code in a method on a super-class,

and make the clients sub-classes (i.e., clients inherit common code)

• What if an algorithm is duplicated in several places, but the copies are SIMILAR rather than IDENTICAL?

• Use the Template Method pattern– Put the common algorithm in a super-class– Clients inherit common code from super-class– Some steps of the algorithm are delegated to subclasses through

polymorphic method calls– Subclasses customize the algorithm by implementing the delegated

steps

Page 23: Computer Science 340 Software Design & Testing Inheritancecs340ta/winter2019/notes/rodham/43... · Template Method Pattern Factory Method Pattern. 2 Class Reuse •Two forms of class

Template Method Pattern

23

Page 24: Computer Science 340 Software Design & Testing Inheritancecs340ta/winter2019/notes/rodham/43... · Template Method Pattern Factory Method Pattern. 2 Class Reuse •Two forms of class

24

/*** An abstract class that is common to several games in* which players play against the others, but only one is* playing at a given time.*/

abstract class Game {

protected int playersCount;

/* A template method : */public final void playOneGame(int playersCount) {this.playersCount = playersCount;initializeGame();int j = 0;while (!endOfGame()) {

makePlay(j);j = (j + 1) % playersCount;

}printWinner();

}

abstract void initializeGame();abstract void makePlay(int player);abstract boolean endOfGame();abstract void printWinner();

}

//Now we can extend this class in order //to implement actual games:

classMonopoly extends Game {

/* Specific declarations for the Monopoly game. */

/* Implementation of abstract methods */void initializeGame() {

// Initialize players// Initialize money

}

void makePlay(int player) {// Process one turn of player

}

boolean endOfGame() {// Return true if game is over // according to Monopoly rules

}

void printWinner() {// Display who won

}

/* Specific methods for the Monopoly game. */// ...

}

Page 25: Computer Science 340 Software Design & Testing Inheritancecs340ta/winter2019/notes/rodham/43... · Template Method Pattern Factory Method Pattern. 2 Class Reuse •Two forms of class

Refactoring with the Template Method Pattern

1. Make the similar code as similar as possible in the classes that duplicate it

– Similar code diverges unnecessarily over time

2. Create a common base class for all classes with similar code

3. Put one copy of the similar code/method(s) in the parent (this becomes the template method)

4. Identify and extract what needs to vary by subclass– Create abstract methods for the code that needs to vary

– Replace the code that needs to vary with calls to the abstract methods in the template method

5. Override the abstract methods in the subclasses with their version of the varying code (pulled out of their copy of the template method override(s))

6. Delete the template method override(s) in the subclasses 25

Page 26: Computer Science 340 Software Design & Testing Inheritancecs340ta/winter2019/notes/rodham/43... · Template Method Pattern Factory Method Pattern. 2 Class Reuse •Two forms of class

26

Factory Method Pattern

• Factory Method pattern– A super-class contains useful functionality that can be

inherited by sub-classes

– The super-class needs to instantiate an object to do its work, but it is a general class and has many potential uses. Therefore, it doesn’t know the concrete class of the object it needs so it can’t instantiate it

– Instantiation of the object is delegated to sub-classes, which do know which concrete class to instantiate

Page 27: Computer Science 340 Software Design & Testing Inheritancecs340ta/winter2019/notes/rodham/43... · Template Method Pattern Factory Method Pattern. 2 Class Reuse •Two forms of class

Factory Method Pattern

27

Page 28: Computer Science 340 Software Design & Testing Inheritancecs340ta/winter2019/notes/rodham/43... · Template Method Pattern Factory Method Pattern. 2 Class Reuse •Two forms of class

28

interface Vehicle{public void drive();

}

class Car implements Vehicle{

@Overridepublic void drive(){System.out.println("Driving a

car...");}

}

class Bus implements Vehicle{

@Overridepublic void drive(){System.out.println("Driving a

Bus...");}

}

abstract class VehicleDriver{

public void driveVehicle(){Vehicle v = makeVehicle();v.drive();

}

public abstract Vehicle makeVehicle();}

class CarDriver extends VehicleDriver{

@Overridepublic Vehicle makeVehicle(){return new Car();

}}

class BusDriver extends VehicleDriver{

@Overridepublic Vehicle makeVehicle(){return new Bus();

}}

Page 29: Computer Science 340 Software Design & Testing Inheritancecs340ta/winter2019/notes/rodham/43... · Template Method Pattern Factory Method Pattern. 2 Class Reuse •Two forms of class

29

public class FactoryMethodPattern {

public static void main(String[] args) {handleVehicle(new CarDriver());handleVehicle(new BusDriver());

}

static void handleVehicle(VehicleDriver vDriver){System.out.println("Handling a new vehicle.");vDriver.driveVehicle();

}}

Handling a new vehicle. Driving a car...Handling a new vehicle. Driving a Bus...