Understanding Solid
Principles
About Me
● Babatunde Otaru
● Software Engineer @ Cotta & Cush
● Tourist
● Liverpool Fan
● Twitter: @mendizel
Case study
Class Book {
Function getTitle() ;
Function getAuthor() ;
Function turnPage() ;
Function printCurrentPage (String printerType) :
Switch (printerType) :
Case “plainTextPrinter” :
return “plain text printout” ;
Case “htmlPrinter” :
return “html printout" ;
Function savePage(String persistenceType) ;
Switch (persistenceType) :
Case “flatFile” :
return “save page in flat file” ;
Case “mysql” :
return “save page in mysql DB” ;
}
New Feature
Can you help print the page in xml format?
Wrong! why?
Class Book {
Function getTitle() ;
Function getAuthor() ;
Function turnPage() ;
Function printCurrentPage (String printerType) :
Switch (printerType) :
Case “plainTextPrinter” :
return “plain text print out” ;
Case “htmlPrinter” :
return “html print out" ;
Case “xmlPrinter” :
Return “xml print out” ;
Function savePage (String persistenceType) :
Switch (persistenceType) :
Case “flatFile” :
return “save in flat file” ;
Case “mysql” :
return “save in mysql DB” ;
}
Why these solid principles?
● System Maintainability
● Changes always happen
● Reduce time to add feature/fix bug
● Easier for other engineers or ‘a future you’ to quickly understand the
codebase
Solid Principles
S - single responsibility principle
O - open/closed principle
L - liskov substitution principle
I - interface segregation principle
D - dependency inversion principle
Solid Principles: Single Responsibility Principle
● Your class should have just one reason to change
● Look for actors in your system
● An actor should have a single job description
● Don’t be confused with a single person acting multiple roles
● Create a class/module for each actor
Solid Principles: Single Responsibility Principle
● Three actors
○ Book Reader
○ Printer Man
○ Records Man
Solid Principles: Single Responsibility Principle
Class Book {
Function getTitle() ;
Function getAuthor() ;
Function turnPage() ;
Function getCurrentPage() ;
Function getNextPage() ;
}
Class Database {
Function saveBook(String databaseType) ;
Switch (databaseType) :
Case “flatFile” :
return “save in flat file” ;
Case “mysql” :
return “save in mysql DB” ;
}
Class Printer {
Function printBookPage (String printerType) :
Switch (printerType) :
Case “plainTextPrinter” :
return “plain text printout” ;
Case “htmlPrinter” :
return “html printout" ;
}
Solid Principles: Open/Closed Principle
● Classes should be open to extension but closed to modifications
● Do not modify classes to add a type of actor in your system
Solid Principles: Open/Closed Principle
Printer Class Case Study:
Class Printer {
Function printBookPage (Printer printer) :
printer.print() ;
}
Interface PrinterInterface {
print() ;
}
Class HtmlPrinter implements PrinterInterface {
Function print() :
return “html print out” ;
}
Class PlainTextPrinter implements PrinterInterface {
Function print() :
return “plain text print out” ;
}
New Feature
Can you help print the page in xml format?
Solid Principles: Liskov Substitution Principle
● Subclasses can substitute parent classes without breaking functionality
(or changing behaviour)
○ New exceptions shouldn’t be thrown in the derived classes
○ Pre conditions cannot be strengthened in the derived classes : integer only
negative example
○ Post conditions cannot be weakened : DB open/close example
Solid Principles: Liskov Substitution Principle
Class Printer {
Function printBookPage (PrinterInterface printer) :
printer.print() ;
}
Interface PrinterInterface {
print() ;
}
Class HtmlPrinter implements PrinterInterface {
Function print() :
return “html print out” ;
}
Class BrowserPrinter extends HtmlPrinter {
Function print() :
If (internet explorer) {
Throw IHateInternetExplorerException();
}
return “print browser page” ;
}
Solid Principles: Interface Segregation Principle
● Interface should represent one discrete cohesive behaviour
● All methods in an interface should be implemented
Solid Principles: Interface Segregation Principle
Interface PrinterInterface {
print() ;
removeInk();
}
Class POSPrinter implements PrinterInterface {
Function print() :
return “POS print out” ;
Function removeInk()
Throw new doesNotHaveInkException;
}
Interface InkableInterface() {
Function removeInk();
}
Solid Principles: Dependency Inversion Principle
● A high level module should not depend on a low level module, both should
depend on abstractions
● Abstractions should never depend upon details, details should depend upon
abstractions
Solid Principles: Dependency Inversion Principle
Class Library {
HtmlPrinter printer = new HtmlPrinter;
Books[] book;
Function printBook (Book) :
Foreach (bookPage) {
This.printer.print(currentPage) ;
}
}
}
Class Library {
PrinterInterface printer;
Books[] book;
Init (PrinterInterface printer) {
This.printer = printer;
}
Function printBook (Book) :
Foreach (bookPage) {
This.printer.print(currentPage) ;
}
}
}
Final Piece!
Class Book {
Function getTitle() ;
Function getAuthor() ;
Function turnPage() ;
Function getCurrentPage() ;
Function getNextPage() ;
}
Class Printer {
Function printBookPage (PrinterInteface printer) :
printer.print() ;
}
Interface PrinterInterface {
print() ;
}
Class HtmlPrinter implements PrinterInterface {
Function print() :
return “html print out” ;
}
Class PlainTextPrinter implements PrinterInterface {
Function print() :
return “plain text print out” ;
}
Class Store {
Function savePage (StoreInterface saver) :
saver.save() ;
}
Interface StoreInterface {
save() ;
}
Class MysqlStore implements StoreInterface {
Function save() :
return “Save Item in Mysql DB” ;
}
Class FlatFileStore implements StoreInterface {
Function save() :
return “Save Item in Flat File” ;
}
Questions….
Kahoot!https://play.kahoot.it/#/k/309f004e-e52e-4f14-bef6-8a2f471e3da8
Thank You

Understanding solid principles

  • 1.
  • 2.
    About Me ● BabatundeOtaru ● Software Engineer @ Cotta & Cush ● Tourist ● Liverpool Fan ● Twitter: @mendizel
  • 3.
    Case study Class Book{ Function getTitle() ; Function getAuthor() ; Function turnPage() ; Function printCurrentPage (String printerType) : Switch (printerType) : Case “plainTextPrinter” : return “plain text printout” ; Case “htmlPrinter” : return “html printout" ; Function savePage(String persistenceType) ; Switch (persistenceType) : Case “flatFile” : return “save page in flat file” ; Case “mysql” : return “save page in mysql DB” ; }
  • 4.
    New Feature Can youhelp print the page in xml format?
  • 5.
    Wrong! why? Class Book{ Function getTitle() ; Function getAuthor() ; Function turnPage() ; Function printCurrentPage (String printerType) : Switch (printerType) : Case “plainTextPrinter” : return “plain text print out” ; Case “htmlPrinter” : return “html print out" ; Case “xmlPrinter” : Return “xml print out” ; Function savePage (String persistenceType) : Switch (persistenceType) : Case “flatFile” : return “save in flat file” ; Case “mysql” : return “save in mysql DB” ; }
  • 6.
    Why these solidprinciples? ● System Maintainability ● Changes always happen ● Reduce time to add feature/fix bug ● Easier for other engineers or ‘a future you’ to quickly understand the codebase
  • 7.
    Solid Principles S -single responsibility principle O - open/closed principle L - liskov substitution principle I - interface segregation principle D - dependency inversion principle
  • 8.
    Solid Principles: SingleResponsibility Principle ● Your class should have just one reason to change ● Look for actors in your system ● An actor should have a single job description ● Don’t be confused with a single person acting multiple roles ● Create a class/module for each actor
  • 9.
    Solid Principles: SingleResponsibility Principle ● Three actors ○ Book Reader ○ Printer Man ○ Records Man
  • 10.
    Solid Principles: SingleResponsibility Principle Class Book { Function getTitle() ; Function getAuthor() ; Function turnPage() ; Function getCurrentPage() ; Function getNextPage() ; } Class Database { Function saveBook(String databaseType) ; Switch (databaseType) : Case “flatFile” : return “save in flat file” ; Case “mysql” : return “save in mysql DB” ; } Class Printer { Function printBookPage (String printerType) : Switch (printerType) : Case “plainTextPrinter” : return “plain text printout” ; Case “htmlPrinter” : return “html printout" ; }
  • 11.
    Solid Principles: Open/ClosedPrinciple ● Classes should be open to extension but closed to modifications ● Do not modify classes to add a type of actor in your system
  • 12.
    Solid Principles: Open/ClosedPrinciple Printer Class Case Study: Class Printer { Function printBookPage (Printer printer) : printer.print() ; } Interface PrinterInterface { print() ; } Class HtmlPrinter implements PrinterInterface { Function print() : return “html print out” ; } Class PlainTextPrinter implements PrinterInterface { Function print() : return “plain text print out” ; }
  • 13.
    New Feature Can youhelp print the page in xml format?
  • 14.
    Solid Principles: LiskovSubstitution Principle ● Subclasses can substitute parent classes without breaking functionality (or changing behaviour) ○ New exceptions shouldn’t be thrown in the derived classes ○ Pre conditions cannot be strengthened in the derived classes : integer only negative example ○ Post conditions cannot be weakened : DB open/close example
  • 15.
    Solid Principles: LiskovSubstitution Principle Class Printer { Function printBookPage (PrinterInterface printer) : printer.print() ; } Interface PrinterInterface { print() ; } Class HtmlPrinter implements PrinterInterface { Function print() : return “html print out” ; } Class BrowserPrinter extends HtmlPrinter { Function print() : If (internet explorer) { Throw IHateInternetExplorerException(); } return “print browser page” ; }
  • 16.
    Solid Principles: InterfaceSegregation Principle ● Interface should represent one discrete cohesive behaviour ● All methods in an interface should be implemented
  • 17.
    Solid Principles: InterfaceSegregation Principle Interface PrinterInterface { print() ; removeInk(); } Class POSPrinter implements PrinterInterface { Function print() : return “POS print out” ; Function removeInk() Throw new doesNotHaveInkException; } Interface InkableInterface() { Function removeInk(); }
  • 18.
    Solid Principles: DependencyInversion Principle ● A high level module should not depend on a low level module, both should depend on abstractions ● Abstractions should never depend upon details, details should depend upon abstractions
  • 19.
    Solid Principles: DependencyInversion Principle Class Library { HtmlPrinter printer = new HtmlPrinter; Books[] book; Function printBook (Book) : Foreach (bookPage) { This.printer.print(currentPage) ; } } } Class Library { PrinterInterface printer; Books[] book; Init (PrinterInterface printer) { This.printer = printer; } Function printBook (Book) : Foreach (bookPage) { This.printer.print(currentPage) ; } } }
  • 20.
    Final Piece! Class Book{ Function getTitle() ; Function getAuthor() ; Function turnPage() ; Function getCurrentPage() ; Function getNextPage() ; } Class Printer { Function printBookPage (PrinterInteface printer) : printer.print() ; } Interface PrinterInterface { print() ; } Class HtmlPrinter implements PrinterInterface { Function print() : return “html print out” ; } Class PlainTextPrinter implements PrinterInterface { Function print() : return “plain text print out” ; } Class Store { Function savePage (StoreInterface saver) : saver.save() ; } Interface StoreInterface { save() ; } Class MysqlStore implements StoreInterface { Function save() : return “Save Item in Mysql DB” ; } Class FlatFileStore implements StoreInterface { Function save() : return “Save Item in Flat File” ; }
  • 21.
  • 22.
  • 23.