Solid principles

2,067 views
1,990 views

Published on

This presentation outlines the SOLID principles with some simple code examples to show the principle in action.

Published in: Technology, Business
0 Comments
9 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
2,067
On SlideShare
0
From Embeds
0
Number of Embeds
14
Actions
Shares
0
Downloads
162
Comments
0
Likes
9
Embeds 0
No embeds

No notes for slide
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Solid principles

    1. 1. SOLID Principles Declan Whelan @dwhelan
    2. 2. SOLID Principles• Single Responsibility Principle• Open Closed Principle• Liskov Substitution Principle• Interface Segregation Principle• Dependency Inversion Principle
    3. 3. Single Responsibility PrincipleThere should be one and only onereason for a class to change.
    4. 4. SRP Violationpublic 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.  }}
    5. 5. SRP Restoredpublic class UserSettingService{  public void changeEmail(User user)  {    if(SecurityService.checkAccess(user))    {       //Grant option to change    }  }}public class SecurityService{  public static boolean checkAccess(User user)  {    //check the access.  }}
    6. 6. Open Closed PrincipleSoftware entities should be open forextension but closed for modification.
    7. 7. A Product FilterWe need a way to filter products by colour.
    8. 8. Class ResponsibilityThe classes’ responsibility is to filterproducts (its job) based off the action offiltering by colour (its behaviour).The ProductFilter is responsible forfiltering products by colour.
    9. 9. Filter By Colourpublic class ProductFilter{ public IEnumerable<Product> ByColor(IList<Product> products, ProductColor productColor) { foreach (var product in products) { if (product.Color == productColor) yield return product; } }}
    10. 10. More Requirements!User: We also need to filter by size.Developer: Just size or colour and size?User: Umm probably both.Developer: Great!
    11. 11. Filter By ColourThe ProductFilter is responsiblefor filtering products by colour,size, colour and size.
    12. 12. public class ProductFilter{ { Filter By Colour public IEnumerable<Product> ByColor(IList<Product> products, ProductColor productColor) foreach (var product in products) { if (product.Color == productColor) yield return product; } } public IEnumerable<Product> ByColorAndSize(IList<Product> products, ProductColor productColor, ProductSize productSize) { foreach (var product in products) { if ((product.Color == productColor) && (product.Size == productSize)) yield return product; } } public IEnumerable<Product> BySize(IList<Product> products, ProductSize productSize) { foreach (var product in products) { if ((product.Size == productSize)) yield return product; } }}
    13. 13. OCP Filter public abstract class ProductFilterSpecification{ public IEnumerable<Product> Filter(IList<Product> products) { return ApplyFilter(products); } protected abstract IEnumerable<Product> ApplyFilter(IList<Product> products);}public class ProductFilter{ public IEnumerable<Product> By(IList<Product> products, ProductFilterSpecification filterSpecification) { return filterSpecification.Filter(products); }}
    14. 14. OCP Filter public class ColorFilterSpecification : ProductFilterSpecification{ private readonly ProductColor productColor; public ColorFilterSpecification(ProductColor productColor) { this.productColor = productColor; } protected override IEnumerable<Product> ApplyFilter(IList<Product> products) { foreach (var product in products) { if (product.Color == productColor) yield return product; } }}
    15. 15. Liskov Substitution PrincipleFunctions that use references to baseclasses must be able to use objects ofderived classes without knowing it.
    16. 16. LSP Violation class 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;! }!}
    17. 17. LSP Violation 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;! }}
    18. 18. LSP Violation class 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 its a rectangle.! ! // It assumes that hes able to set the width and height as for the base class! ! System.out.println(r.getArea());! ! // now hes surprised to see that the area is 100 instead of 50.! }}
    19. 19. Interface Segregation PrincipleClients should not be forced to dependon interfaces that they do not use.
    20. 20. ISP Example public abstract class Animal{ public abstract void Feed();}public class Dog : Animal{ public override void Feed() { // do something }}public class Rattlesnake : Animal{ public override void Feed() { // do something }}
    21. 21. ISP Violation public abstract class Animal{ public abstract void Feed(); public abstract void Groom();}public class Rattlesnake : Animal{ public override void Feed() { // do something } public override void Groom() { // ignore }}
    22. 22. ISP Restored public interface IPet{ void Groom();}public abstract class Animal{ public abstract void Feed();}public class Dog : Animal, IPet{ public override void Feed() { // do something } public void Groom() { // do something }}public class Rattlesnake : Animal{ public override void Feed() { // do something }
    23. 23. Handoutpublic class CustomMembershipProvider : MembershipProvider{ public override string ApplicationName { get { throw new Exception("The method or operation is not implemented."); } set { throw new Exception("The method or operation is not implemented."); } } public override bool ChangePassword(string username, string oldPassword, stringnewPassword) { throw new Exception("The method or operation is not implemented."); } public override bool ChangePasswordQuestionAndAnswer(string username, string
    24. 24. Dependency Inversion PrincipleHigh level modules should not dependupon low level modules. Both shoulddepend upon abstractions.Abstractions should not depend upondetails. Details should depend uponabstractions.
    25. 25. DIP Violation public class OrderProcessor{ public decimal CalculateTotal(Order order) { decimal itemTotal = order.GetItemTotal(); decimal discountAmount = DiscountCalculator.CalculateDiscount(order); decimal taxAmount = 0.0M; if (order.Country == "US") taxAmount = FindTaxAmount(order); else if (order.Country == "UK") taxAmount = FindVatAmount(order); decimal total = itemTotal - discountAmount + taxAmount; return total; } private decimal FindVatAmount(Order order) { // find the UK value added tax somehow return 10.0M; } private decimal FindTaxAmount(Order order) { // find the US tax somehow return 10.0M; }}
    26. 26. DIP Restored public interface IDiscountCalculator{ decimal CalculateDiscount(Order order);}public interface ITaxStrategy{ decimal FindTaxAmount(Order order);}public class OrderProcessor{ private readonly IDiscountCalculator _discountCalculator; private readonly ITaxStrategy _taxStrategy; public OrderProcessor(IDiscountCalculator discountCalculator, ITaxStrategy taxStrategy) { _taxStrategy = taxStrategy; _discountCalculator = discountCalculator; } public decimal CalculateTotal(Order order) { decimal itemTotal = order.GetItemTotal(); decimal discountAmount = _discountCalculator.CalculateDiscount(order); decimal taxAmount = _taxStrategy.FindTaxAmount(order); decimal total = itemTotal - discountAmount + taxAmount; return total; }}
    27. 27. DIP Restored public class DiscountCalculatorAdapter : IDiscountCalculator{ public decimal CalculateDiscount(Order order) { return DiscountCalculator.CalculateDiscount(order); }}public class USTaxStrategy : ITaxStrategy{ public decimal FindTaxAmount(Order order) { }}public class UKTaxStrategy : ITaxStrategy{ public decimal FindTaxAmount(Order order) { }}
    28. 28. ReadingClean Code: A Handbook of Agile SoftwareCraftsmanship Robert C. MartinDesign Patterns: Elements of Reusable Object-OrientedSoftware Erich Gamma, Richard Helm, Ralph Johnson,and John VlissidesAgile Principles, Patterns and Practices in C#Robert C. MartinLean Architecture: for Agile Software DevelopmentJames O. Coplien and Gertrud Bjørnvig
    29. 29. Photo CreditsSOLID Motivational Posters, by Derick Bailey, is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License. http://lostechies.com/derickbailey/files/2011/03/SOLID_6EC97F9C.jpg http://lostechies.com/derickbailey/files/2011/03/SingleResponsibilityPrinciple2_71060858.jpg http://lostechies.com/derickbailey/files/2011/03/OpenClosedPrinciple2_2C596E17.jpg http://lostechies.com/derickbailey/files/2011/03/LiskovSubtitutionPrinciple_52BB5162.jpg http://lostechies.com/derickbailey/files/2011/03/InterfaceSegregationPrinciple_60216468.jpg http://lostechies.com/derickbailey/files/2011/03/DependencyInversionPrinciple_0278F9E2.jpg

    ×