design principles - solid
TRANSCRIPT
![Page 1: Design principles - SOLID](https://reader038.vdocuments.us/reader038/viewer/2022103010/58f30a0e1a28abbe1a8b4583/html5/thumbnails/1.jpg)
Design PrinciplesPranalee Rokde
![Page 2: Design principles - SOLID](https://reader038.vdocuments.us/reader038/viewer/2022103010/58f30a0e1a28abbe1a8b4583/html5/thumbnails/2.jpg)
WHY?• Difficult to understand code
• Difficult to make safe changes, existing code gets change while adding new feature as product expands
• Difficult to write jUnits
• Find 1 bug and have to search entire code base to fix for every implementation
• Code review is difficult
![Page 3: Design principles - SOLID](https://reader038.vdocuments.us/reader038/viewer/2022103010/58f30a0e1a28abbe1a8b4583/html5/thumbnails/3.jpg)
SYMPTOMS OF BAD DESIGN• Rigidity
• Fragility
• Immobility
• Viscosity
![Page 4: Design principles - SOLID](https://reader038.vdocuments.us/reader038/viewer/2022103010/58f30a0e1a28abbe1a8b4583/html5/thumbnails/4.jpg)
RIGIDITY• It is hard to change because every change affects too many
other parts of the system.
![Page 5: Design principles - SOLID](https://reader038.vdocuments.us/reader038/viewer/2022103010/58f30a0e1a28abbe1a8b4583/html5/thumbnails/5.jpg)
FRAGILITY• When you make a change, unexpected parts of the system
break.
![Page 6: Design principles - SOLID](https://reader038.vdocuments.us/reader038/viewer/2022103010/58f30a0e1a28abbe1a8b4583/html5/thumbnails/6.jpg)
IMMOBILITY• Inability to reuse software from parts of the same project or
from other projects.
• It often happens that one engineer will discover that he needs a module that is similar to one that another engineer wrote. However, it also often happens that the module in question has too much baggage that it depends upon.
• It is hard to reuse in another application because it cannot be separated from the current application.
![Page 7: Design principles - SOLID](https://reader038.vdocuments.us/reader038/viewer/2022103010/58f30a0e1a28abbe1a8b4583/html5/thumbnails/7.jpg)
VISCOSITY• When the hacks are easy to employ than the design
preserving methods
![Page 8: Design principles - SOLID](https://reader038.vdocuments.us/reader038/viewer/2022103010/58f30a0e1a28abbe1a8b4583/html5/thumbnails/8.jpg)
SOLID• Single Responsibility Principle
• Open Closed Principle
• Liskov's Substitution Principle
• Interface Segregation Principle
• Dependency Inversion Principle
![Page 9: Design principles - SOLID](https://reader038.vdocuments.us/reader038/viewer/2022103010/58f30a0e1a28abbe1a8b4583/html5/thumbnails/9.jpg)
![Page 10: Design principles - SOLID](https://reader038.vdocuments.us/reader038/viewer/2022103010/58f30a0e1a28abbe1a8b4583/html5/thumbnails/10.jpg)
SRP – SINGLE RESPONSIBILITY PRINCIPLE• A class should have only one responsibility.
• A class should have only one reason to change.
• If we have 2 reasons to change for a class, we have to split the functionality in two classes.
![Page 11: Design principles - SOLID](https://reader038.vdocuments.us/reader038/viewer/2022103010/58f30a0e1a28abbe1a8b4583/html5/thumbnails/11.jpg)
SINGLE RESPONSIBILITY PRINCIPLE
public class Employee {public Money calculatePay() ...
public String reportHours() ...
public void save() ...}
![Page 12: Design principles - SOLID](https://reader038.vdocuments.us/reader038/viewer/2022103010/58f30a0e1a28abbe1a8b4583/html5/thumbnails/12.jpg)
SINGLE RESPONSIBILITY PRINCIPLE
public class Employee { public Money calculatePay() ...
}
public class EmployeeReporter { public String reportHours(Employee e) ...
}
public class EmployeeRepository { public void save(Employee e) ...
}
![Page 13: Design principles - SOLID](https://reader038.vdocuments.us/reader038/viewer/2022103010/58f30a0e1a28abbe1a8b4583/html5/thumbnails/13.jpg)
Single Responsibility Principlepublic class UserSettingService{ public void changeEmail(User user) { if(checkAccess(user)) { //Grant option to change } } public boolean checkAccess(User user) { //Verify if the user is valid. }}
![Page 14: Design principles - SOLID](https://reader038.vdocuments.us/reader038/viewer/2022103010/58f30a0e1a28abbe1a8b4583/html5/thumbnails/14.jpg)
Single Responsibility Principlepublic class SecurityService{ public static boolean checkAccess(User user) { //check the access. }}
public class UserSettingService{ public void changeEmail(User user) { if(SecurityService.checkAccess(user)) { //Grant option to change } }}
![Page 15: Design principles - SOLID](https://reader038.vdocuments.us/reader038/viewer/2022103010/58f30a0e1a28abbe1a8b4583/html5/thumbnails/15.jpg)
Single Responsibility Principle• The SRP is one of the simplest of the principles, and one of
the hardest to get right
• An axis of change is only an axis of change if the changes actually occur.
• It is not wise to apply the SRP, or any other principle for that matter, if there is no symptom
• i.e. Don’t fall into trap of needless complexity
![Page 16: Design principles - SOLID](https://reader038.vdocuments.us/reader038/viewer/2022103010/58f30a0e1a28abbe1a8b4583/html5/thumbnails/16.jpg)
OCP - OPEN CLOSED PRINCIPLE • Software entities should be open for extension but closed for
modification
![Page 17: Design principles - SOLID](https://reader038.vdocuments.us/reader038/viewer/2022103010/58f30a0e1a28abbe1a8b4583/html5/thumbnails/17.jpg)
OCP - Example Version 1 public class AreaCalculator { public double Area(Rectangle[] shapes) { double area = 0; foreach (var shape in shapes) { area += shape.Width*shape.Height; }
return area; } }
public class Rectangle { public double Width { get; set; } public double Height { get; set; } }
![Page 18: Design principles - SOLID](https://reader038.vdocuments.us/reader038/viewer/2022103010/58f30a0e1a28abbe1a8b4583/html5/thumbnails/18.jpg)
OCP - Example Version 2 public double Area(object[] shapes) { double area = 0; foreach (var shape in shapes) { if (shape is Rectangle) { Rectangle rectangle = (Rectangle) shape; area += rectangle.Width*rectangle.Height; } else { Circle circle = (Circle)shape; area += circle.Radius * circle.Radius * Math.PI; } }
return area; }
public class Rectangle { public double Width { get; set; } public double Height { get; set; } }
public class Circle { public double Radius { get; set; } }
![Page 19: Design principles - SOLID](https://reader038.vdocuments.us/reader038/viewer/2022103010/58f30a0e1a28abbe1a8b4583/html5/thumbnails/19.jpg)
OCP - Example Version 3public double Area(Shape[] shapes){ double area = 0; foreach (var shape in shapes) { area += shape.Area(); }
return area;}
public class Rectangle : Shape{ public double Width { get; set; } public double Height { get; set; } public override double Area() { return Width*Height; }}
public class Circle : Shape{ public double Radius { get; set; } public override double Area() { return Radius*Radius*Math.PI; }}
![Page 20: Design principles - SOLID](https://reader038.vdocuments.us/reader038/viewer/2022103010/58f30a0e1a28abbe1a8b4583/html5/thumbnails/20.jpg)
OCP• OCP is heart of object oriented design
• OCP leads to design patterns like Factory, Observer
![Page 21: Design principles - SOLID](https://reader038.vdocuments.us/reader038/viewer/2022103010/58f30a0e1a28abbe1a8b4583/html5/thumbnails/21.jpg)
![Page 22: Design principles - SOLID](https://reader038.vdocuments.us/reader038/viewer/2022103010/58f30a0e1a28abbe1a8b4583/html5/thumbnails/22.jpg)
SRP/OCP Benefits• Less merge conflicts
• Less changes to existing code means easy to trace bug in regression testing
• Saved efforts on rewriting jUnits as existing code has less chances to change
![Page 23: Design principles - SOLID](https://reader038.vdocuments.us/reader038/viewer/2022103010/58f30a0e1a28abbe1a8b4583/html5/thumbnails/23.jpg)
LSP - LIKOV'S SUBSTITUTION PRINCIPLE• Child classes should never break the parent class' type
definitions
![Page 24: Design principles - SOLID](https://reader038.vdocuments.us/reader038/viewer/2022103010/58f30a0e1a28abbe1a8b4583/html5/thumbnails/24.jpg)
LSP - LIKOV'S SUBSTITUTION PRINCIPLEclass Rectangle{
protected int m_width;protected int m_height;
public void setWidth(int width){m_width = width;
}
public void setHeight(int height){m_height = height;
}
public int getWidth(){return m_width;
}
public int getHeight(){return m_height;
}
public int getArea(){return m_width * m_height;
}}
class Square extends Rectangle {
public void setWidth(int width){m_width = width;m_height = width;
}
public void setHeight(int height){m_width = height;m_height = height;
}
}
![Page 25: Design principles - SOLID](https://reader038.vdocuments.us/reader038/viewer/2022103010/58f30a0e1a28abbe1a8b4583/html5/thumbnails/25.jpg)
LSP - LIKOV'S SUBSTITUTION PRINCIPLEclass LspTest{
private static Rectangle getNewRectangle(){
// it can be an object returned by some factory ... return new Square();
}
public static void main (String args[]){
Rectangle r = LspTest.getNewRectangle();r.setWidth(5);r.setHeight(10);// user knows that r it's a rectangle. // It assumes that he's able to set the width and height as for the base class
System.out.println(r.getArea());// now he's surprised to see that the area is 100 instead of 50.
}}
![Page 26: Design principles - SOLID](https://reader038.vdocuments.us/reader038/viewer/2022103010/58f30a0e1a28abbe1a8b4583/html5/thumbnails/26.jpg)
LSP - LIKOV'S SUBSTITUTION PRINCIPLE• LSP must be followed correctly in order for OCP to function
correctly
![Page 27: Design principles - SOLID](https://reader038.vdocuments.us/reader038/viewer/2022103010/58f30a0e1a28abbe1a8b4583/html5/thumbnails/27.jpg)
![Page 28: Design principles - SOLID](https://reader038.vdocuments.us/reader038/viewer/2022103010/58f30a0e1a28abbe1a8b4583/html5/thumbnails/28.jpg)
ISP - INTERFACE SEGREGATION PRINCIPLE
• Fat interfaces
• No clients should be forced to implement methods it doesn't use.
• Abstract class - sub classes with doNothing override
![Page 29: Design principles - SOLID](https://reader038.vdocuments.us/reader038/viewer/2022103010/58f30a0e1a28abbe1a8b4583/html5/thumbnails/29.jpg)
ISP - Violation Exampleinterface IMessage {
List<String> getToAddresses();
String getMessageBody();
String getSubject();
boolean Send();}
![Page 30: Design principles - SOLID](https://reader038.vdocuments.us/reader038/viewer/2022103010/58f30a0e1a28abbe1a8b4583/html5/thumbnails/30.jpg)
ISP - Violation Exampleclass EmailMessage implements IMessage {
public List<String> getToAddresses() {// return addressesreturn null;
}public String getMessageBody() {
// return message bodyreturn null;
}public String getSubject() {
// return subjectreturn null;
}public boolean Send() {
// send emailreturn false;
}}
class SMSMessage implements IMessage {public List<String> getToAddresses() {
// return addressesreturn null;
}public String getMessageBody() {
// return message bodyreturn null;
}public String getSubject() {
throw new RuntimeException("SMS don't have subject");}public boolean Send() {
// send smsreturn false;
}
}
![Page 31: Design principles - SOLID](https://reader038.vdocuments.us/reader038/viewer/2022103010/58f30a0e1a28abbe1a8b4583/html5/thumbnails/31.jpg)
ISP Exampleinterface IMessage {
List<String> getToAddresses();
String getMessageBody();
boolean Send();}
interface IEmailMessage extends IMessage{List<String> getBccAddresses();String getSubject();
}
![Page 32: Design principles - SOLID](https://reader038.vdocuments.us/reader038/viewer/2022103010/58f30a0e1a28abbe1a8b4583/html5/thumbnails/32.jpg)
ISP Exampleclass EmailMessage implements IEmailMessage {
public List<String> getToAddresses() {// return addressesreturn null;
}public String getMessageBody() {
// return message bodyreturn null;
}public String getSubject() {
// return subjectreturn null;
}public boolean Send() {
// send emailreturn false;
}public List<String> getBccAddresses() {
// return bcc addressesreturn null;
}}
class SMSMessage implements IMessage {public List<String> getToAddresses() {
// return addressesreturn null;
}public String getMessageBody() {
// return message bodyreturn null;
}public boolean Send() {
// send smsreturn false;
}}
![Page 33: Design principles - SOLID](https://reader038.vdocuments.us/reader038/viewer/2022103010/58f30a0e1a28abbe1a8b4583/html5/thumbnails/33.jpg)
ISP• Fat interfaces lead to inadvertent couplings
![Page 34: Design principles - SOLID](https://reader038.vdocuments.us/reader038/viewer/2022103010/58f30a0e1a28abbe1a8b4583/html5/thumbnails/34.jpg)
![Page 35: Design principles - SOLID](https://reader038.vdocuments.us/reader038/viewer/2022103010/58f30a0e1a28abbe1a8b4583/html5/thumbnails/35.jpg)
DIP - DEPENDENCY INVERSION PRINCIPLEpublic class ElectricPowerSwitch { public LightBulb lightBulb; public boolean on; public ElectricPowerSwitch(LightBulb lightBulb) { this.lightBulb = lightBulb; this.on = false; } public boolean isOn() { return this.on; } public void press(){ boolean checkOn = isOn(); if (checkOn) { lightBulb.turnOff(); this.on = false; } else { lightBulb.turnOn(); this.on = true; } }}
public class LightBulb { public void turnOn() { System.out.println("LightBulb: Bulb turned on..."); } public void turnOff() { System.out.println("LightBulb: Bulb turned off..."); }}
![Page 36: Design principles - SOLID](https://reader038.vdocuments.us/reader038/viewer/2022103010/58f30a0e1a28abbe1a8b4583/html5/thumbnails/36.jpg)
DIP - DEPENDENCY INVERSION PRINCIPLEpublic interface Switch { boolean isOn(); void press();}
public class ElectricPowerSwitch implements Switch { public Switchable client; public boolean on; public ElectricPowerSwitch(Switchable client) { this.client = client; this.on = false; } public boolean isOn() { return this.on; } public void press(){ boolean checkOn = isOn(); if (checkOn) { client.turnOff(); this.on = false; } else { client.turnOn(); this.on = true; } }}
public interface Switchable { void turnOn(); void turnOff();}
public class LightBulb implements Switchable { @Override public void turnOn() { System.out.println("LightBulb: Bulb turned on..."); } @Override public void turnOff() { System.out.println("LightBulb: Bulb turned off..."); }}
![Page 37: Design principles - SOLID](https://reader038.vdocuments.us/reader038/viewer/2022103010/58f30a0e1a28abbe1a8b4583/html5/thumbnails/37.jpg)
DIP
![Page 38: Design principles - SOLID](https://reader038.vdocuments.us/reader038/viewer/2022103010/58f30a0e1a28abbe1a8b4583/html5/thumbnails/38.jpg)
Few more…• DRY/WET
• Abstract class
• Package principles
![Page 39: Design principles - SOLID](https://reader038.vdocuments.us/reader038/viewer/2022103010/58f30a0e1a28abbe1a8b4583/html5/thumbnails/39.jpg)
Thank YouReferences
• Articles by Robert Martin