Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Upcoming SlideShare
Loading in …5
×

Applying SOLID Principles

701 views

Published on

How do you tell whether one design is better than another? This talk provides the answer. By walking through a simple example business problem and its software solution, we examine a few key principles that can be applied to make designs simpler, easier to maintain and change, and overall better.

Published in: Technology
• Full Name
Comment goes here.

Are you sure you want to Yes No
Your message goes here
• Be the first to comment

• Be the first to like this

Applying SOLID Principles

1. 1. OO SOLID Applying SOLID principles to improve object-oriented designs
2. 2. Say we have a mechanic shop...
3. 3. ServiceOrder AddPart(Part) Total() 1..* Part Name Price
4. 4. ! public class Part  {  private decimal price;    public Part(string name, decimal price)  {  this.price = price;  }    public decimal Price  {  get { return price; }  set { price = value; }  }    }
5. 5. ! public class ServiceOrder {  private List<Part> parts;    public ServiceOrder() {  parts = new List<Part>();  }    public void AddPart(Part part) {  parts.Add(part);  }    public decimal Total() {  decimal total = 0;  foreach (Part aPart in parts) {  total += aPart.Price;  }  return total;  }  }
6. 6. Now we want to specify additional quantities of each part. (because we are lazy)
7. 7. ServiceOrder partsAndQtys : Dictionary AddPart(Part) Total() 1..* Part Name Price
8. 8. ! public class ServiceOrder  {  private Dictionary<Part, int> partsAndQuantities;    public ServiceOrder() {  partsAndQuantities = new Dictionary<Part, int>();  }    public void AddPart(Part part) {  this.AddPart(part, 1);  }    public void AddPart(Part part, int quantity) {  int currentQuantity = 0;  if (partsAndQuantities.ContainsKey(part)) {  currentQuantity = partsAndQuantities[part];  }  int newQuantity = currentQuantity + quantity;  partsAndQuantities.Add(part, newQuantity);  }    public decimal Total() {  decimal total = 0;  foreach (Part aPart in partsAndQuantities.Keys) {  int quantity = partsAndQuantities[aPart];  total += aPart.Price * quantity;  }  return total;  }  }
9. 9. ServiceOrder AddPart(Part, Qty) Total() 1 1..* LineItem Part Quantity Part * 1 Name Price
10. 10. ! public class LineItem  {  private Part part;    private int quantity;    public LineItem(Part part, int quantity) {  this.part = part;  this.quantity = quantity;  }    public Part Part {  get { return part; }  }    public int Quantity {  get { return quantity; }  private set { quantity = value; }  }  }
11. 11. public class ServiceOrder  {  private List<LineItem> lineItems;    public ServiceOrder() {  lineItems = new List<LineItem>();  }    public void AddPart(Part part) {  this.AddPart(part, 1);  }    public void AddPart(Part part, int quantity) {  LineItem lineItem = new LineItem(part, quantity);  lineItems.Add(lineItem);  }    public decimal Total() {  decimal total = 0;  foreach (LineItem aLineItem in lineItems) {  total += aLineItem.Part.Price * aLineItem.Quantity;  }    return total;  }  }
12. 12. S ingle Responsibility Principle
13. 13. Now we want to add a markup for each part. (because we want to track profit margin)
14. 14. ServiceOrder AddPart(Part, Qty) Total() 1 1..* Part LineItem Part Quantity * 1 Name MarkupPercentage WholesalePrice
15. 15. ! public class Part  {  private string name;  private decimal wholesalePrice;  private int markupPercentage;    public Part(string name, decimal price) :this(name, price, 0)  {}    public Part(string name, decimal price, int markupPercentage) {  this.name = name;  this.wholesalePrice = price;  this.markupPercentage = markupPercentage;  }    public string Name {  get { return name; }  }    public decimal WholesalePrice {  get { return wholesalePrice; }  }    public int MarkupPercentage {  get { return markupPercentage; }  }  }
16. 16. ! public class ServiceOrder  {  private List<LineItem> lineItems;    public ServiceOrder() {  lineItems = new List<LineItem>();  }    public void AddPart(Part part) {  this.AddPart(part, 1);  }    public void AddPart(Part part, int additionalQuantity) {  LineItem lineItem = new LineItem(part, additionalQuantity);  lineItems.Add(lineItem);  }    public decimal Total() {  decimal total = 0;  foreach (LineItem aLineItem in lineItems) {  total += aLineItem.Part.WholesalePrice  * (aLineItem.Part.MarkupPercentage/100m + 1)  * aLineItem.Quantity;  }  return total;  }  }
17. 17. ServiceOrder AddPart(Part, Qty) Total() 1 1..* Part LineItem Part Quantity LineTotal() * 1 Name MarkupPercentage WholesalePrice
18. 18. ! // New methods in the Part class   public decimal Price {  get { return wholesalePrice * MarkupMultiplier(); }  }  ! private decimal MarkupMultiplier() {  return (markupPercentage / 100m + 1);  } ! !   // And one in the LineItem class    public decimal LineTotal() {  return part.Price * quantity;  }
19. 19. ! // In the ServiceOrder class...    public decimal Total() {    decimal total = 0;  foreach (LineItem aLineItem in lineItems) {  total += aLineItem.LineTotal();  }  return total;    }
20. 20. O pen/Closed Principle
21. 21. Now we want to add labor costs. (because we want to make more money)
22. 22. Part Name MarkupPercentage WholesalePrice Price()
23. 23. Part Name MarkupPercentage WholesalePrice Labor Price Price()
24. 24. ! public class Labor : Part  {  public Labor(string name, decimal price) : base(name, price) {}  }
25. 25. Item Name CalculatePrice() Labor Price CalculatePrice() Part MarkupPercentage WholesalePrice CalculatePrice()
26. 26. ! public interface Item  {  string Name { get; }  decimal CalculatePrice();  }
27. 27. L iskov Substitution Principle
28. 28. Now we want to generate receipts. (because we want to seem professionalish)
29. 29. Presentation Layer Business Layer ReceiptGenerator ServiceOrder PrintReceipt() AddPart(Part, Qty) Total()
30. 30. ! public class ReceiptGenerator  {  private FixItMechanicsSystem system;  private EpsonTMT88IVPrinter epsonTMT88IVPrinter;  private string initString = "sasllkslsl398383fa";   public void PrintReceipt() {  ServiceOrder order = system.FinalizeOrder();   string receiptString = "Total........ \$" + order.Total();  epsonTMT88IVPrinter.Initialize(initString);  epsonTMT88IVPrinter.PrintBwMed239(receiptString);  epsonTMT88IVPrinter.Flush(); }  }
31. 31. Presentation Layer ReceiptGenerator PrintReceipt() Business Layer Receipt Total() ServiceOrder AddPart(Part, Qty) Total()
32. 32.   // In the ReciptGenerator class.    public void PrintReceipt() {  IReceipt receipt = system.FinalizeOrder();   string receiptString = "Total........ \$" + receipt.Total();  epsonTMT88IVPrinter.Initialize(initString);  epsonTMT88IVPrinter.PrintBwMed239(receiptString);  epsonTMT88IVPrinter.Flush();  }
33. 33. I nterface Segregation Principle
34. 34. We need to print to a new printer. (because we’re growing and they don’t make the old one anymore)
35. 35. ReceiptGenerator PrintReceipt() EpsonT88IVPrinter 1 Initialize(String) PrintBwMed239(String) Flush()
36. 36. ! public class ReceiptGenerator  {  private FixItMechanicsSystem system;  private EpsonTMT88IV epsonTMT88IVPrinter;  private string initString = "sasllkslsl398383fa";   public void PrintReceipt() {  Receipt receipt = system.FinalizeOrder();   string receiptString = "Total........ \$" + receipt.Total();  epsonTMT88IVPrinter.Initialize(initString);  epsonTMT88IVPrinter.PrintBwMed239(receiptString);  epsonTMT88IVPrinter.Flush(); }  }
37. 37. ReceiptGenerator PrintReceipt() EpsonPrinterAdapter 1 EpsonT88IVPrinter 1 GenericPrinter Print(String) SamsungPrinterAdapter 1 SamsungSRP350 Initialize(String) Initialize(String) PrintBwMed239(String) ProcessPages(String) Flush()
38. 38.   public class ReceiptGenerator  {  private FixItMechanicsSystem system;  private IGenericPrinter printer;    public void PrintReceipt() {  Receipt receipt = system.FinalizeOrder();  string receiptString = "Total........ \$" + receipt.Total();  printer.Print(receiptString);  }  }
39. 39.   public class EpsonPrinterAdapter : IGenericPrinter  {  private EpsonTMT88IV epsonTMT88IVPrinter;  private string initString = "sasllkslsl398383fa";    public void Print(string printString) {  epsonTMT88IVPrinter.Initialize(initString);  epsonTMT88IVPrinter.PrintBwMed239(printString);  epsonTMT88IVPrinter.Flush();  }  }
40. 40.   public class SamsungPrinterAdapter : IGenericPrinter  {  private SamsungSRP350 samsungSRP350Printer;  private string initString = "aksreiufgu";    public void Print(string printString) {  samsungSRP350Printer.Init(initString);  samsungSRP350Printer.ProcessPages(printString);  }  }
41. 41. D ependency Inversion Principle
42. 42. S ingle Responsibility Principle O pen/Closed Principle L iskov Substitution Principle I nterface Segregation Principle D ependency Inversion Principle
43. 43. Questions?
44. 44. X Poor Design • Duplication • Ambiguity • Complexity
45. 45. ✓ Good Design ✓ Low Coupling ✓ High Cohesion
46. 46. Questions?