Softwerkskammer - Coding Dojo
Racing Car Katas
S.O.L.I.D & Refactoring
https://www.slideshare.net/georgberky/solid-refactoring-racing-car-katas
let’s practice together
● all professionals practice
● how about us programmers?
● when was the last time you sat down to really
understand a problem?
● tonight we have time to do that
the ground rules
● write tests
● work together in pairs
● write down
– �: what did you learn
– �: what made you lose focus
– �: what confused you
– � : what annoyed you
● share with everybody
● be excellent to each other
the ground rules
● if you have the keyboard, you get to decide what to type
● if you have the keyboard and you don’t know what to
type, ask for help
● if you are asked for help, kindly respond to the best of
your ability
● if you are not asked, but you see an opportunity for
improvement or learning, choose an appropriate
moment to mention it like the next green test or the
retrospective
from: Emily Bache – The Coding Dojo Handbook
the exercise
● choose one exercise
● add tests for the class
– Leaderboard: add tests using SelfDrivingCar
● write down where SOLID principles were violated
● repeat
● share with your fellow craftspeople
SOLID
● Single responsibility principle (SRP)
● Open/closed principle (OCP)
● Liskov substitution principle (LSP)
● Interface segregation principle (ISP)
● Dependency inversion principle (DIP)
single responsibility principle
● responsibility = reason to change
● if nothing ever changed: no problem
● change is the fundamental reality of our
business
SRP - ExpensesReport
● store/retrieve expenses:
– Excel, CSV, database
– cause: infrastructure
● compile report from expenses
– taxes, sorting
– cause: business rules
● format and print report
– plain text, HTML
– cause: cosmetic
open/closed principle
● open for extension, closed for modification
● huh? ��♂�‍ ️
● when facing change: introduce abstractions
● abstraction = interface (see DIP)
● we need to open/close our design
● this is a voluntary choice
● driven by the fact/requirement of change
● avoid BDUF, practice refactoring
OCP - FizzBuzz
● add one if per number: �
● possible abstractions:
– NumberSayer (immediate choice)
– NumberStrategy (higher abstraction)
● open: extending behavior by adding interface
implementation
● closed: original code does not change when adding a
new number
● cf.: Craig Larman – Protected Variation
Liskov substitution principle
● polymorphism must be transparent to clients
● the client must not care which implementation is used
● instanceof is a smell: broken abstraction
● all contracts of superclass must be kept:
– preconditions
– postconditions
– invariants
– history constraint
LSP - square/rectangle
● class Square extends Rectangle ?
● change width of square
● height has to change too
● contract of Rectangle:
postcondition: setWidth(n) getWidth ()== n⇒
● contract of Square:
invariant: height == width
LSP - square/rectangle
● you cannot drop in a square for a rectangle
● unit tests help you see these contracts
● try to use the same test for subclasses!
● OOP inheritance does not have to follow real
live inheritance
● cf.: design by contract
interface segregation principle
● do not depend on more than you need
● keep your interfaces slim
● extract interface from dependency if you only
use some of the methods
ISP – primitive obsession
● use first class collections:
– do you need all 32 public methods of java.util.List ?
– clarity: Calendar instead of List<Appointment>
● use value types
– DeviceId instead of String
– 76 exposed methods of String
ISP – service locator
● <T> ServiceLocator.getService(Class<T> class)
● infinite number of methods
● ServiceLocator.getService(String.class)
● invisible preconditions:
– serviceClass needs to be in directory
– only discovered at runtime
● constructor:
– explicit precondition
– discovered at compile time
dependency inversion principle
● do not depend on low level details
● depend on high level abstractions instead
● business rules (high level) should not change
when implementation details (low level) change
● e.g. report calculation has to change when data
storage changes?
DIP – button/light
● class Button
– void toggle()
● class LightBulb
– void turnOn()
– void turnOff()
● change: button should work with TV
● class TV
– void powerOn()
– void powerOff()
DIP – button/light
● option 1:
– public Button(LightBulb lightBulb)
– public Button(TV tv)
– void toggle():
● if(lightBulb != null && tv == null) { … }
● if(tv != null && lightBulb == null) { … }
– now add five more classes: �
DIP – button/light
● option 2:
– interface Switchable
● void turnOn()
● void turnOff()
– class LightBulb implements Switchable
– class TV implements Switchable
– public Button(Switchable switchable)
– void toggle(): straightforward
DIP – button/light
● client: Button
– depends on high level abstraction
– “something that can be switched on and off”
– interface, abstract class, multimethod
● low level details:
– turnOn/powerOn, turnOff/powerOff
– depend on abstraction too
– by implementing it
● no dependency on low level details
● interface “owned” by the client
the exercise
● racing car katas
● by Emily Bache & Luca Minudel
● git clone
https://github.com/emilybache/Racing-Car-Katas.git

SOLID refactoring - racing car katas

  • 1.
    Softwerkskammer - CodingDojo Racing Car Katas S.O.L.I.D & Refactoring
  • 2.
  • 3.
    let’s practice together ●all professionals practice ● how about us programmers? ● when was the last time you sat down to really understand a problem? ● tonight we have time to do that
  • 4.
    the ground rules ●write tests ● work together in pairs ● write down – �: what did you learn – �: what made you lose focus – �: what confused you – � : what annoyed you ● share with everybody ● be excellent to each other
  • 5.
    the ground rules ●if you have the keyboard, you get to decide what to type ● if you have the keyboard and you don’t know what to type, ask for help ● if you are asked for help, kindly respond to the best of your ability ● if you are not asked, but you see an opportunity for improvement or learning, choose an appropriate moment to mention it like the next green test or the retrospective from: Emily Bache – The Coding Dojo Handbook
  • 6.
    the exercise ● chooseone exercise ● add tests for the class – Leaderboard: add tests using SelfDrivingCar ● write down where SOLID principles were violated ● repeat ● share with your fellow craftspeople
  • 7.
    SOLID ● Single responsibilityprinciple (SRP) ● Open/closed principle (OCP) ● Liskov substitution principle (LSP) ● Interface segregation principle (ISP) ● Dependency inversion principle (DIP)
  • 8.
    single responsibility principle ●responsibility = reason to change ● if nothing ever changed: no problem ● change is the fundamental reality of our business
  • 9.
    SRP - ExpensesReport ●store/retrieve expenses: – Excel, CSV, database – cause: infrastructure ● compile report from expenses – taxes, sorting – cause: business rules ● format and print report – plain text, HTML – cause: cosmetic
  • 10.
    open/closed principle ● openfor extension, closed for modification ● huh? ��♂�‍ ️ ● when facing change: introduce abstractions ● abstraction = interface (see DIP) ● we need to open/close our design ● this is a voluntary choice ● driven by the fact/requirement of change ● avoid BDUF, practice refactoring
  • 11.
    OCP - FizzBuzz ●add one if per number: � ● possible abstractions: – NumberSayer (immediate choice) – NumberStrategy (higher abstraction) ● open: extending behavior by adding interface implementation ● closed: original code does not change when adding a new number ● cf.: Craig Larman – Protected Variation
  • 12.
    Liskov substitution principle ●polymorphism must be transparent to clients ● the client must not care which implementation is used ● instanceof is a smell: broken abstraction ● all contracts of superclass must be kept: – preconditions – postconditions – invariants – history constraint
  • 13.
    LSP - square/rectangle ●class Square extends Rectangle ? ● change width of square ● height has to change too ● contract of Rectangle: postcondition: setWidth(n) getWidth ()== n⇒ ● contract of Square: invariant: height == width
  • 14.
    LSP - square/rectangle ●you cannot drop in a square for a rectangle ● unit tests help you see these contracts ● try to use the same test for subclasses! ● OOP inheritance does not have to follow real live inheritance ● cf.: design by contract
  • 15.
    interface segregation principle ●do not depend on more than you need ● keep your interfaces slim ● extract interface from dependency if you only use some of the methods
  • 16.
    ISP – primitiveobsession ● use first class collections: – do you need all 32 public methods of java.util.List ? – clarity: Calendar instead of List<Appointment> ● use value types – DeviceId instead of String – 76 exposed methods of String
  • 17.
    ISP – servicelocator ● <T> ServiceLocator.getService(Class<T> class) ● infinite number of methods ● ServiceLocator.getService(String.class) ● invisible preconditions: – serviceClass needs to be in directory – only discovered at runtime ● constructor: – explicit precondition – discovered at compile time
  • 18.
    dependency inversion principle ●do not depend on low level details ● depend on high level abstractions instead ● business rules (high level) should not change when implementation details (low level) change ● e.g. report calculation has to change when data storage changes?
  • 19.
    DIP – button/light ●class Button – void toggle() ● class LightBulb – void turnOn() – void turnOff() ● change: button should work with TV ● class TV – void powerOn() – void powerOff()
  • 20.
    DIP – button/light ●option 1: – public Button(LightBulb lightBulb) – public Button(TV tv) – void toggle(): ● if(lightBulb != null && tv == null) { … } ● if(tv != null && lightBulb == null) { … } – now add five more classes: �
  • 21.
    DIP – button/light ●option 2: – interface Switchable ● void turnOn() ● void turnOff() – class LightBulb implements Switchable – class TV implements Switchable – public Button(Switchable switchable) – void toggle(): straightforward
  • 22.
    DIP – button/light ●client: Button – depends on high level abstraction – “something that can be switched on and off” – interface, abstract class, multimethod ● low level details: – turnOn/powerOn, turnOff/powerOff – depend on abstraction too – by implementing it ● no dependency on low level details ● interface “owned” by the client
  • 23.
    the exercise ● racingcar katas ● by Emily Bache & Luca Minudel ● git clone https://github.com/emilybache/Racing-Car-Katas.git