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.
OO SOLID
Applying SOLID principles to improve object-oriented designs
Say we have a mechanic
shop...
ServiceOrder

AddPart(Part)
Total()

1..*
Part
Name
Price
!
public class Part

{

private decimal price;



public Part(string name, decimal price)

{

this.price = price;

}



pu...
!
public class ServiceOrder {

private List<Part> parts;



public ServiceOrder() {

parts = new List<Part>();

}



publi...
Now we want to specify additional
quantities of each part.	

(because we are lazy)
ServiceOrder
partsAndQtys : Dictionary
AddPart(Part)
Total()

1..*
Part
Name
Price
!

public class ServiceOrder

{

private Dictionary<Part, int> partsAndQuantities;




public ServiceOrder() {

partsAndQu...
ServiceOrder

AddPart(Part, Qty)
Total()
1

1..*
LineItem
Part
Quantity

Part
*

1

Name
Price
!
public class LineItem

{

private Part part;



private int quantity;



public LineItem(Part part, int quantity) {

thi...
public class ServiceOrder

{

private List<LineItem> lineItems;



public ServiceOrder() {

lineItems = new List<LineItem>...
S ingle Responsibility Principle
Now we want to add a markup
for each part.	

(because we want to track
profit margin)
ServiceOrder

AddPart(Part, Qty)
Total()
1

1..*
Part

LineItem
Part
Quantity

*

1

Name
MarkupPercentage
WholesalePrice
!

public class Part

{

private string name;

private decimal wholesalePrice;

private int markupPercentage;




public P...
!

public class ServiceOrder

{

private List<LineItem> lineItems;




public ServiceOrder() {

lineItems = new List<LineI...
ServiceOrder

AddPart(Part, Qty)
Total()
1

1..*
Part

LineItem
Part
Quantity
LineTotal()

*

1

Name
MarkupPercentage
Who...
!
// New methods in the Part class	


public decimal Price {

get { return wholesalePrice * MarkupMultiplier(); }

}


!
p...
!
// In the ServiceOrder class...



public decimal Total() {



decimal total = 0;

foreach (LineItem aLineItem in lineIt...
O pen/Closed Principle
Now we want to add labor costs.	

(because we want to 	

make more money)
Part
Name
MarkupPercentage
WholesalePrice
Price()
Part
Name
MarkupPercentage
WholesalePrice

Labor
Price
Price()
!
public class Labor : Part

{

public Labor(string name, decimal price)	
: base(name, price)	
{}

}



Item
Name
CalculatePrice()

Labor
Price
CalculatePrice()

Part
MarkupPercentage
WholesalePrice
CalculatePrice()
!
public interface Item

{

string Name { get; }

decimal CalculatePrice();

}
L iskov Substitution Principle
Now we want to generate
receipts.	

(because we want to	

seem professionalish)
Presentation Layer

Business Layer

ReceiptGenerator

ServiceOrder

PrintReceipt()

AddPart(Part, Qty)
Total()
!
public class ReceiptGenerator

{

private FixItMechanicsSystem system;

private EpsonTMT88IVPrinter epsonTMT88IVPrinter;...
Presentation Layer
ReceiptGenerator

PrintReceipt()

Business Layer
Receipt

Total()

ServiceOrder

AddPart(Part, Qty)
Tot...


// In the ReciptGenerator class.



public void PrintReceipt() {

IReceipt receipt = system.FinalizeOrder();	


string r...
I nterface Segregation Principle
We need to print to a new
printer.	

(because we’re growing and they
don’t make the old one anymore)
ReceiptGenerator

PrintReceipt()

EpsonT88IVPrinter
1

Initialize(String)
PrintBwMed239(String)
Flush()
!
public class ReceiptGenerator

{

private FixItMechanicsSystem system;

private EpsonTMT88IV epsonTMT88IVPrinter;

priva...
ReceiptGenerator

PrintReceipt()

EpsonPrinterAdapter

1
EpsonT88IVPrinter

1

GenericPrinter

Print(String)

SamsungPrint...


public class ReceiptGenerator

{

private FixItMechanicsSystem system;

private IGenericPrinter printer;



public void ...


public class EpsonPrinterAdapter : IGenericPrinter

{

private EpsonTMT88IV epsonTMT88IVPrinter;

private string initStr...


public class SamsungPrinterAdapter : IGenericPrinter

{

private SamsungSRP350 samsungSRP350Printer;

private string ini...
D ependency Inversion Principle
S ingle Responsibility Principle
O pen/Closed Principle
L iskov Substitution Principle
I nterface Segregation Principle
D ...
Questions?
X
Poor
Design

• Duplication
• Ambiguity
• Complexity
✓
Good
Design

✓ Low Coupling
✓ High Cohesion
Questions?
Applying SOLID Principles
Upcoming SlideShare
Loading in …5
×

Applying SOLID Principles

695 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
  • 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?

×