design principles - solid

39
Design Principles Pranalee Rokde

Upload: pranalee-rokde

Post on 16-Apr-2017

60 views

Category:

Software


2 download

TRANSCRIPT

Page 1: Design principles - SOLID

Design PrinciplesPranalee Rokde

Page 2: Design principles - SOLID

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

SYMPTOMS OF BAD DESIGN• Rigidity

• Fragility

• Immobility

• Viscosity

Page 4: Design principles - SOLID

RIGIDITY• It is hard to change because every change affects too many

other parts of the system.

Page 5: Design principles - SOLID

FRAGILITY• When you make a change, unexpected parts of the system

break.

Page 6: Design principles - SOLID

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

VISCOSITY•  When the hacks are easy to employ than the design

preserving methods

Page 8: Design principles - SOLID

SOLID• Single Responsibility Principle

• Open Closed Principle

• Liskov's Substitution Principle

• Interface Segregation Principle

• Dependency Inversion Principle

Page 9: Design principles - SOLID
Page 10: Design principles - SOLID

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

SINGLE RESPONSIBILITY PRINCIPLE

public class Employee {public Money calculatePay() ...

public String reportHours() ...

public void save() ...}

Page 12: Design principles - SOLID

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

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

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

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

OCP - OPEN CLOSED PRINCIPLE • Software entities should be open for extension but closed for

modification

Page 17: Design principles - SOLID

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

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

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

OCP• OCP is heart of object oriented design

• OCP leads to design patterns like Factory, Observer

Page 21: Design principles - SOLID
Page 22: Design principles - SOLID

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

LSP - LIKOV'S SUBSTITUTION PRINCIPLE• Child classes should never break the parent class' type

definitions

Page 24: Design principles - SOLID

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

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

LSP - LIKOV'S SUBSTITUTION PRINCIPLE• LSP must be followed correctly in order for OCP to function

correctly

Page 27: Design principles - SOLID
Page 28: Design principles - SOLID

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

ISP - Violation Exampleinterface IMessage {

List<String> getToAddresses();

String getMessageBody();

String getSubject();

boolean Send();}

Page 30: Design principles - SOLID

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

ISP Exampleinterface IMessage {

List<String> getToAddresses();

String getMessageBody();

boolean Send();}

interface IEmailMessage extends IMessage{List<String> getBccAddresses();String getSubject();

}

Page 32: Design principles - SOLID

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

ISP• Fat interfaces lead to inadvertent couplings

Page 34: Design principles - SOLID
Page 35: Design principles - SOLID

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

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

DIP

Page 38: Design principles - SOLID

Few more…• DRY/WET

• Abstract class

• Package principles

Page 39: Design principles - SOLID

Thank YouReferences

• Articles by Robert Martin