Presentation is loading. Please wait.

Presentation is loading. Please wait.

High Cohesion Low Coupling Old Standards for Object Oriented Programming.

Similar presentations


Presentation on theme: "High Cohesion Low Coupling Old Standards for Object Oriented Programming."— Presentation transcript:

1

2 High Cohesion Low 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 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

6 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

7 Single Responsibility Principle Demo

8 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.

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

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

11 Dependency Inversion Naïve Example Demo

12 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.

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(" Text for Survey Type 2 Goes Here "); case 2: editableText.Append(" Text for Survey Type 2 Goes Here "); case 3: default: editableText.Append(" Text for Survey Type 3 Goes Here "); } return editableText.ToString(); }

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

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 Extensibility Template Pattern (Inheritance) public abstract Survey{ protected abstract string GetDefaultEditableText(); public string GetEmailText() { … string defaultText = GetDefaultEditableText(); … return somthingHere; } public SurveyType1{ protected string GetDefaultEditableText() { return " Text for Survey Type 1 Goes Here "; }

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 Interface Segregation Princple Clients shouldn't be forced to implement interfaces they don't use

22 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

23 Interface Segregation Princple Interface Idoor { void Lock(); void UnLock(); bool IsOpen(); } Public Class Door : Idoor { public void Lock() {} public void UnLock(){} bool IsOpen(){} }

24 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() {} }

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

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

27 Demeter class Wallet attr_accessor :cash end class Customer has_one :wallet end class Paperboy def collect_money(customer, due_amount) if customer.wallet.cash < due_ammount raise InsufficientFundsError else customer.wallet.cash -= due_amount @collected_amount += due_amount end

28 Demeter The fix: class Wallet attr_accessor :cash def withdraw(amount) raise InsufficientFundsError if amount > cash cash -= amount amount end class Customer has_one :wallet # behavior delegation def pay(amount) @wallet.withdraw(amount) end class Paperboy def collect_money(customer, due_amount) @collected_amount += customer.pay(due_amount) end

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 Customer{ FirstName{get;set} LastName{get;set} Order GetOrder() } public class PreferredCustomer : Customer{ double GetDiscount() } //voilation foreach(Customer c in CustomerList){ if(c is PreferredCustomer){ GetDiscount(); }

32 Liskov Subtypes should restrict the subclass, not expand it. Use Composition to solve expansion violations

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.


Download ppt "High Cohesion Low Coupling Old Standards for Object Oriented Programming."

Similar presentations


Ads by Google