inheritance - the myth of code reuse | andrei raifura | codeway 2015

Post on 15-Feb-2017

235 Views

Category:

Software

1 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Andrei Raifura iOS Department Manager, YOPESO

#CodeWăy

Inheritance - The myth of code reuse

• How does Inheritance help us to reuse the code

• Why it doesn’t work

• The pitfalls of Inheritance

• To use or not to use

Agenda

• Encapsulation

• Abstraction

• Inheritance

• Polymorphism

OOP principlesI will teach you OOP

Inheritance

“…It is a mechanism for code reuse and to allow independent extensions of the original software via public classes and interfaces…”

Wikipedia, Inheritance (object-oriented programming)

Inheritance

‣ Two ears ‣ For legs ‣ Tail

Animal

Case study

Case study

CustomerYou

Case study

Can you program a Toyota Corolla for me?

CustomerYou

Case study

Mm..Sure!!

CustomerYou

Toyota Corolla

Wheels

Manufacturer

Transmission

4

Toyota

Front-wheel drive

Defining Car

class Car { let frontLeft = Wheel() let frontRight = Wheel() let rearLeft = Wheel() let rearRight = Wheel()

Defining Car

class Car { let frontLeft = Wheel() let frontRight = Wheel() let rearLeft = Wheel() let rearRight = Wheel() var manufacturer: String { get { return "Undefined" } }

Defining Car

class Car { . . .

func turnLeft(degrees: Double) { frontLeft.turnLeft(degrees) frontRight.turnLeft(degrees) } func turnRight(degrees: Double) { frontLeft.turnRight(degrees) frontRight.turnRight(degrees) }

Defining Car

class Car { . . .

func accelerate(kph: Double) { frontLeft.rotate(kph) frontRight.rotate(kph) } }

Defining Wheel

class Wheel { private var angle = 0.0 private var rotationSpeed = 0.0 func turnRight(degrees: Double) { angle += degrees } func turnLeft(degrees: Double) { angle -= degrees } func rotate(kph: Double) { rotationSpeed = kph } }

Defining Toyota Corolla

class ToyotaCorolla: Car { override var manufacturer: String { get { return "Toyota" } } }

Class Diagram

- manufacturer - turnLeft - turnRight - accelerate

Car

ToyotaCorolla

- turnLeft - turnRight - rotate

Wheel

Case study

Great! Now, i’d like to have a Toyota Corolla Sport

CustomerYou

Case study

Ok! will do!

CustomerYou

Toyota Corolla

Wheels

Manufacturer

Transmission

4

Toyota

Front-wheel drive

Toyota Corolla

Wheels

Manufacturer

Transmission

4

Toyota

Front-wheel drive

Toyota Corolla Sport

Wheels

Manufacturer

Transmission

4

Toyota

Rear-wheel drive

Defining Toyota Corolla Sport

class ToyotaCorollaSport: ToyotaCorolla { override func accelerate(kph: Double) { rearLeft.rotate(kph) rearRight.rotate(kph) } }

Class Diagram

- manufacturer - turnLeft - turnRight - accelerate

Car

ToyotaCorolla

- turnLeft - turnRight - rotate

Wheel

Class Diagram

- manufacturer - turnLeft - turnRight - accelerate

Car

ToyotaCorollaSport

ToyotaCorolla

- turnLeft - turnRight - rotate

Wheel

Case study

Woww! Now a Honda Civic and a Honda Civic

Sport

CustomerYou

Case study

Mmnn.. ok

CustomerYou

Honda Civic

Wheels

Manufacturer

Transmission

4

Front-wheel drive

Honda

Honda Civic Sport

Wheels

Manufacturer

Transmission

4

Rear-wheel drive

Honda

Class Diagram

- manufacturer - turnLeft - turnRight - accelerate

Car

ToyotaCorollaSport

ToyotaCorolla

- turnLeft - turnRight - rotate

Wheel

Class Diagram

- manufacturer - turnLeft - turnRight - accelerate

Car

ToyotaCorollaSport

ToyotaCorolla

- turnLeft - turnRight - rotate

Wheel

HondaCivic

HondaCivicSport

Defining Front-wheel Drive

class FrontWheelDriveCar: Car { override func accelerate(kph: Double) { frontLeft.rotate(kph) frontRight.rotate(kph) } }

Defining Rear-wheel Drive

class RearWheelDriveCar: Car { override func accelerate(kph: Double) { rearLeft.rotate(kph) rearRight.rotate(kph) } }

Class Diagram

- manufacturer - turnLeft - turnRight - accelerate

Car

ToyotaCorollaSport

ToyotaCorolla

- turnLeft - turnRight - rotate

Wheel

HondaCivic

HondaCivicSport

Class Diagram

- manufacturer - turnLeft - turnRight - accelerate

Car

FrontWheelDriveCar

ToyotaCorollaSport

RearWheelDriveCar

ToyotaCorolla

- turnLeft - turnRight - rotate

Wheel

HondaCivic HondaCivicSport

Refactoring Toyota Corolla

class ToyotaCorolla: FrontWheelDriveCar { override var manufacturer: String { get { return "Toyota" } } }

Refactoring Toyota Corolla Sport

class ToyotaCorollaSport: RearWheelDriveCar { override var manufacturer: String { get { return "Toyota" } } }

Defining Honda Civic

class HondaCivic: FrontWheelDriveCar { override var manufacturer: String { get { return "Honda" } } }

Defining Honda Civic Sport

class HondaCivicSport: RearWheelDriveCar { override var manufacturer: String { get { return "Honda" } } }

Lexus GX

Wheels

Manufacturer

Transmission

4

All-wheel drive

Lexus

Class Diagram

- manufacturer - turnLeft - turnRight - accelerate

Car

FrontWheelDriveCar

ToyotaCorollaSport

RearWheelDriveCar

ToyotaCorolla

- turnLeft - turnRight - rotate

Wheel

HondaCivic HondaCivicSport

Class Diagram

- manufacturer - turnLeft - turnRight - accelerate

Car

FrontWheelDriveCar

ToyotaCorollaSport

RearWheelDriveCar

ToyotaCorolla

- turnLeft - turnRight - rotate

Wheel

HondaCivic HondaCivicSport

AllWheelDriveCar

LexusGX

Defining All-wheel Drive

class AllWheelDriveCar: Car { override func accelerate(kph: Double) { frontLeft.rotate(kph) frontRight.rotate(kph) rearLeft.rotate(kph) rearRight.rotate(kph) } }

Defining Lexus GX

class LexusGX: AllWheelDriveCar { override var manufacturer: String { get { return "Lexus" } } }

Case study

Amazing! But, can you make

me an experimental car?

CustomerYou

Case study

It will switch between two-wheel drive and all-wheel

drive…

CustomerYou

Case study

And will turn with all four wheels.

CustomerYou

Experimental

Wheels

Manufacturer

Transmission

4

Front-wheel drive

Experimental

Experimental

Wheels

Manufacturer

Transmission

4

Front-wheel drive & All-wheel drive

Experimental

Experimental

Wheels

Manufacturer

Transmission

4

Front-wheel drive & All-wheel drive

Experimental

Steering All-wheel steering

Are you Seriously?

Class Diagram

- manufacturer - turnLeft - turnRight - accelerate

Car

FrontWheelDriveCar RearWheelDriveCar

- turnLeft - turnRight - rotate

Wheel

AllWheelDriveCar

Class Diagram

- manufacturer - turnLeft - turnRight - accelerate

Car

FrontWheelDriveCar RearWheelDriveCar

- turnLeft - turnRight - rotate

Wheel

AllWheelDriveCar

ExperimentalCar

Class Diagram

- manufacturer - turnLeft - turnRight - accelerate

Car

FrontWheelDriveCar RearWheelDriveCar

- turnLeft - turnRight - rotate

Wheel

AllWheelDriveCar

ExperimentalCar

Class Diagram

- manufacturer - turnLeft - turnRight - accelerate

Car

FrontWheelDriveCar RearWheelDriveCar

- turnLeft - turnRight - rotate

Wheel

AllWheelDriveCar

ExperimentalCar

Class Diagram

- manufacturer - turnLeft - turnRight - accelerate

Car

FrontWheelDriveCar RearWheelDriveCar

- turnLeft - turnRight - rotate

Wheel

AllWheelDriveCar

ExperimentalCar

The Diamond of Dread

Code reuse

“…It is a mechanism for code reuse and to allow independent extensions of the original software via public classes and interfaces…”

Wikipedia, Inheritance (object-oriented programming)

Code reuse

“…It is a mechanism for code reuse and to allow independent extensions of the original software via public classes and interfaces…”

Wikipedia, Inheritance (object-oriented programming)

Solutions

Demo

Inheritance pitfalls

• A very tight binding between a superclass and its subclasses

• Makes the code fragile

• Difficult to debug

• Inheritance relationships generally can't be altered at runtime.

• Leads to violation of Liskov Substitution Principle

• Difficult to test

Inheritance pitfalls

• A very tight binding between a superclass and its subclasses

• Makes the code fragile

• Difficult to debug

• Inheritance relationships generally can't be altered at runtime.

• Leads to violation of Liskov Substitution Principle

• Difficult to test

Inheritance pitfalls

• A very tight binding between a superclass and its subclasses

• Difficult to debug

• Inheritance relationships generally can't be altered at runtime.

• Leads to violation of Liskov Substitution Principle

• Difficult to test

• Makes the code fragile

Inheritance pitfalls

• A very tight binding between a superclass and its subclasses

• Difficult to debug

• Inheritance relationships generally can't be altered at runtime.

• Leads to violation of Liskov Substitution Principle

• Difficult to test

• Makes the code fragile

Inheritance pitfalls

• A very tight binding between a superclass and its subclasses

• Difficult to debug

• Inheritance relationships generally can't be altered at runtime.

• Leads to violation of Liskov Substitution Principle

• Difficult to test

• Makes the code fragile

Liskov Substitution Principle

Subtypes must be substitutable for their base types.

Robert C. Martin (Uncle Bob)

Violation of LSP

class File { var path: String! var data: NSData! func loadData() { // Retrieve data from disk } func saveData() { // Write data to disk } }

class ReadOnlyFile: File { override func saveData() { print("Cannot write data") } }

Violation of LSP

Inheritance pitfalls

• A very tight binding between a superclass and its subclasses

• Difficult to debug

• Inheritance relationships generally can't be altered at runtime.

• Leads to violation of Liskov Substitution Principle

• Difficult to test

• Makes the code fragile

Inheritance pitfalls

• A very tight binding between a superclass and its subclasses

• Makes the code fragile

• Difficult to debug

• Inheritance relationships generally can't be altered at runtime.

• Leads to violation of Liskov Substitution Principle

• Difficult to test

Should we avoid inheritance altogether?

To use?

Use Inheritance when your derived class truly is the type you're extending.And it will always be!

The Employee

- firstName - lastName - age - department

Employee

The Employee and the Student

- firstName - lastName - age - year - faculty

Student

- firstName - lastName - age - department

Employee

The Employee and the Student

- firstName - lastName - age

Person

- department

Employee

- year - faculty

Student

The Employee and the Student

- firstName - lastName - age

Person

- department

Employee

- year - faculty

Student

I am a Student. And an Employee.

The Employee and the Student

- firstName - lastName - age

Person

- department

Employee

- year - faculty

Student

I am a Student. And an Employee.

I've just become unemployed.

The Employee and the Student

- firstName - lastName - age

Person

Occupation

- department

Employee- year - faculty

Student Unemployed

Or not to use?

How about polymorphism?

Consider using Protocols* to achieve a polymorphic behaviour.* Also known as Interfaces in other languages

I need to reuse some code from superclass. No

The derived class is almost the extending type No

The derived class is the extending type but might change in the future No

I need a polymorphic behaviour No

The derived class truly is the extending type. And it won't change. I swear!

Yes

To use or Not to use?

• How does Inheritance help us to reuse the code

• Why it doesn’t work

• The pitfalls of Inheritance

• To use or not to use

Review

Use Inheritance Wisely!

Questions?

Contacts

Raifura Andrei iOS Department Manager, YOPESO

andrei.raifura@yopeso.com

thelvis4@gmail.com

#CodeWăy

top related