1 / 35

Principles of Object Oriented Design

Principles of Object Oriented Design. - John Teague & Mahendra Mavani. High Cohesion Low Coupling. Old Standards for Object Oriented Programming. Problems Solved. Maintainability Easier to Test Less Resistance to Change Fear to Change Code Leads to Old Stinky Code

archie
Download Presentation

Principles of Object Oriented Design

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Principles of Object Oriented Design - John Teague & MahendraMavani

  2. High CohesionLow Coupling Old Standards for Object Oriented Programming

  3. Problems Solved • Maintainability • Easier to Test • Less Resistance to Change • Fear to Change Code Leads to Old Stinky Code • Reduces Repetition (DRY) • Don’t Cut and Paste!!!! • Allows For Continuous Improvement • Essential for Agile Development

  4. Topics To Discuss • Single Responsibility Principle • Dependency Inversion Principle • Open Closed Principle • Interface Segregation Principle • Law of Demeter • Liskov Substitution Principle

  5. Single Responsibility Principle What is Responsibility? • Reason for change • Find how many reason you can think of for you class/method to change • If more than one, then your design violates SRP

  6. Single Responsibility Principle Requirement : Send monthly account statement to the customer <demo>

  7. Single Responsibility Principle Problem:- • we have more than one responsibility • reading transaction record • Formatting • Sending Email • Different user may want different email format • IT Dept. may decide to change how data is stored • Bank might want to start using third party email sending utility.

  8. Single Responsibility Principle • Refactor • public class TransactionRepository {…. } • public class HTMLMailFormater {….} • public class EmailService {…….. } • Demo

  9. Dependency Inversion • Depend upon abstraction • High level module should not depend upon low level module implementation, rather depend upon abstraction • Template pattern

  10. Dependency Inversion • Naïve Example Demo

  11. Dependency Inversion Problem:- • All the client must use text file to store transaction • Sends email in HTML format only • Code in BankAccount class, doesn’t depend upon storage but still can’t be tested in isolation.

  12. Open Closed Principle • Classes should be Open to Extensibility and Closed to Modifications • To Change behavior, you want to add new code instead of modifying existing Code. • May not have access to code

  13. Why Keep Code Closed To Modifications • Changing Existing Code is Risky. • Can be Time Consuming in a Non-Refactored code base.

  14. Code Not Designed on OCP private string SetDefaultEditableText() { StringBuilder editableText = new StringBuilder(); switch ( SurveyManager.CurrentSurvey.TypeID ) { case 1: editableText.Append("<p>Text for Survey Type 2 Goes Here</p>"); case 2: editableText.Append("<p>Text for Survey Type 2 Goes Here</p>"); case 3: default: editableText.Append("<p>Text for Survey Type 3 Goes Here</p>"); } return editableText.ToString(); }

  15. Desigined For Extensibility Strategy Pattern (Composition focused) interface ISurveyEmailFormatter{ string GetDefaultEditableText(); } public SurveyType1EmailFormatter : ISurveyEmailFormatter{ public string GetDefaultEditableText(){ return "<p>Text for Survey Type 1 Goes Here</p>"; } } public SurveyType2EmailFormatter : ISurveyEmailFormatter{ public string GetDefaultEditableText(){ return "<p>Text for Survey Type 2 Goes Here</p>"; } } public SurveyType3EmailFormatter : ISurveyEmailFormatter{ public string GetDefaultEditableText(){ return "<p>Text for Survey Type 3 Goes Here</p>"; } }

  16. Strategy Pattern Cont’d public class Survey{ IEmailFormatter _emailFormatter; public Survey(IEmailFormmater emailFormater){ _emailFormatter = emailFormatter; } public string GetEmailDefaultText(){ return _emailFormatter.GetDefaultEditableText(); } }

  17. Designed for ExtensibilityTemplate Pattern (Inheritance) public abstract Survey{ protected abstract string GetDefaultEditableText(); public string GetEmailText() { … string defaultText = GetDefaultEditableText(); … return somthingHere; } } public SurveyType1{ protected string GetDefaultEditableText() { return "<p>Text for Survey Type 1 Goes Here</p>"; } }

  18. Extensibility Only Goes So far • Change is going to occur and you can’t keep everything from changing • Must use judgment on which parts of your application are more likely to change and focus extensibility there.

  19. Law of Demeter • Don’t Talk To Strangers • Methods Should Only Talk To: • Methods and fields on the Object • Parameters passed into the method • Objects Created within the method • Only one “dot” • foo.bar.baz (bad)

  20. Demeter • Breaking this principle breaks encapsulation, and tightens coupling. • Refactoring much more difficult • Test Setup becomes much more difficult

  21. Demeter public class Wallet { double Cash{get;set;} } public class Customer { Wallet Wallet{get;set;} } public class Paperboy { public double AmountCollected{get;set} public void CollectMoney(Customer customer, double amount){ if(customer.Wallet.Cash < amount) throw new InsufficientFundsException(); customer.Wallet.Cash -= amount; AmountCollected += customer.Wallet.Cash; } }

  22. Demeter • The fix: public class Wallet { double Cash{get;set;} public double Withdraw(double amount){ if(Cash < amount) throw new InsufficientFundsException(); Cash -= amount; return amount; } } public class Customer { Wallet Wallet{get;set;} public double Pay(double amount) { Wallet.Withdraw(amount); } } public class Paperboy { public double AmountCollected{get;set} public void CollectMoney(Customer customer, double amount) { AmountCollected += customer.Pay(amount); } } http://www.ccs.neu.edu/research/demeter/demeter-method/LawOfDemeter/paper-boy/demeter.pdf

  23. Interface Segregation Princple • Clients shouldn't be forced to implement interfaces they don't use

  24. Interface Segregation Princple • Example of FAT or Polluted Interface • Try implementing custom Membership Provider in ASP.NET 2.0. • You just need to implement 27 methods/properties

  25. Interface Segregation Princple Interface Idoor { void Lock(); void UnLock(); bool IsOpen(); } Public Class Door : Idoor { public void Lock() {} public void UnLock(){} bool IsOpen(){} } <Demo>

  26. Interface Segregation Princple • Consider one implementation as security door which need to ring alarm if door is kept open for longer duration. Interface Idoor { void Lock(); void UnLock(); bool IsOpen(); void Timeout(); } public class SecurityDoor : Idoor { void Lock() {} void UnLock() {} bool IsOpen() {} void Timeout() {} } <Demo>

  27. Interface Segregation Princple Problem • All type of door are not timed • By adding Timeout into IDoor we are polluting our interface

  28. Interface Segregation Princple public interface ITimerClient { void TimeOut(); } public class SecurityDoor : IDoor, ITimerClient { public void TimeOut() {…….} }

  29. Liskov Substitution Principle • All sub-classes must be substitutable for their base class.

  30. Liskov violation • Structural • You should not have to explicitly cast a base object to it’s subclass to do something. • Behavior • Subtypes should behave in a consistent manner in terms of their clients

  31. Liskov Example public class LinkedList { public void copyInto(LinkedListdest) { dest.clear(); int n = getLength(); for(inti = 0; i < n; ++i){ dest.addElement(getElementAt(i)); } } } public class Set : LinkedList { ... /** * Adds element to this set, provided * element is not already in the set */ public void addElement(Object element) { if(!hasElement(element)) { super.addElement(element); } } }

  32. Liskov • Behavior of CopyInto will not always be consistent • Set To Set is okay • LinkedList to LinkedList is okay • Set to LinkedList is okay • LinkedList to Set behaves differently • Linked List with {1, 2, 3, 2, 1} becomes {1, 2, 3} http://doodleproject.sourceforge.net/articles/2000/liskovSubstitutionPrinciple.html

  33. Bottom line … • SRP • Only one reason to change • DIP • “Don’t call me, I’ll call you” • OCP • Open for extension, Closed for modification • LSP • Sub types should be substitutable for their bases types • LoD • “Don’t talk to strangers” • ISP • Clients should not be forced to depend on methods they do not use

  34. Remember… Always code as if the guy maintaining your code would be a violent psychopath and he knows where you live.

  35. References • Uncle Bob’s blog • http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod • Los Techies Topic of the Month • http://www.lostechies.com/blogs/chad_myers/archive/2008/03/07/pablo-s-topic-of-the-month-march-solid-principles.aspx

More Related