high cohesion low coupling old standards for object oriented programming

34

Upload: logan-wheeler

Post on 18-Jan-2016

222 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: High Cohesion Low Coupling Old Standards for Object Oriented Programming
Page 2: High Cohesion Low Coupling Old Standards for Object Oriented Programming

High Cohesion

Low Coupling

Old Standards for Object Oriented Programming

Page 3: High Cohesion Low Coupling Old Standards for Object Oriented Programming

Problems SolvedMaintainabilityEasier to TestLess Resistance to Change

Fear to Change Code Leads to Old Stinky CodeReduces Repetition (DRY)

Don’t Cut and Paste!!!!Allows For Continuous ImprovementEssential for Agile Development

Page 4: High Cohesion Low Coupling Old Standards for Object Oriented Programming

Topics To DiscussSingle Responsibility PrincipleDependency Inversion PrincipleOpen Closed PrincipleInterface Segregation PrincipleLaw of DemeterLiskov Substitution Principle

Page 5: High Cohesion Low Coupling Old Standards for Object Oriented Programming

Open Closed PrincipleClasses should be Open to Extensibility and

Closed to ModificationsTo Change behavior, you want to add new code

instead of modifying existing Code.May not have access to code

Page 6: High Cohesion Low Coupling Old Standards for Object Oriented Programming

Single Responsibility PrincipleWhat 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

Page 7: High Cohesion Low Coupling Old Standards for Object Oriented Programming

Single Responsibility Principle

Demo

Page 8: High Cohesion Low Coupling Old Standards for Object Oriented Programming

Single Responsibility PrincipleProblem:-we have more than one responsibility

reading transaction recordFormattingSending Email

Different user may want different email formatIT Dept. may decide to change how data is

storedBank might want to start using third party

email sending utility.

Page 9: High Cohesion Low Coupling Old Standards for Object Oriented Programming

Single Responsibility PrincipleRefactorpublic class TransactionRepository

{…. }public class HTMLMailFormater

{….}public class EmailService {…….. }

Demo

Page 10: High Cohesion Low Coupling Old Standards for Object Oriented Programming

Dependency InversionDepend upon abstractionHigh level module should not

depend upon low level module implementation, rather depend upon abstraction

Template pattern

Page 11: High Cohesion Low Coupling Old Standards for Object Oriented Programming

Dependency InversionNaïve Example Demo

Page 12: High Cohesion Low Coupling Old Standards for Object Oriented Programming

Dependency InversionProblem:-All the client must use text file to

store transactionSends email in HTML format onlyCode in BankAccount class, doesn’t

depend upon storage but still can’t be tested in isolation.

Page 13: High Cohesion Low Coupling Old Standards for Object Oriented Programming

Why Keep Code Closed To ModificationsChanging Existing Code is Risky.Can be Time Consuming in a Non-Refactored

code base.

Page 14: High Cohesion Low Coupling Old Standards for Object Oriented Programming

Code Not Designed on OCPprivate 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();

}

Page 15: High Cohesion Low Coupling Old Standards for Object Oriented Programming

Desigined For ExtensibilityStrategy 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>";}

}

Page 16: High Cohesion Low Coupling Old Standards for Object Oriented Programming

Strategy Pattern Cont’dpublic class Survey{

IEmailFormatter _emailFormatter;public Survey(IEmailFormmater emailFormater){

_emailFormatter = emailFormatter;}

public string GetEmailDefaultText(){return _emailFormatter.GetDefaultEditableText();

}

}

Page 17: High Cohesion Low Coupling Old Standards for Object Oriented Programming

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>";}

}

Page 18: High Cohesion Low Coupling Old Standards for Object Oriented Programming

Extensibility Only Goes So farChange is going to occur and you can’t keep

everything from changingMust use judgment on which parts of your

application are more likely to change and focus extensibility there.

Page 19: High Cohesion Low Coupling Old Standards for Object Oriented Programming

Law of DemeterDon’t Talk To StrangersMethods Should Only Talk To:

Methods and fields on the ObjectParameters passed into the methodObjects Created within the method

Only one “dot”foo.bar.baz (bad)

Page 20: High Cohesion Low Coupling Old Standards for Object Oriented Programming

DemeterBreaking this principle breaks encapsulation,

and tightens coupling.Refactoring much more difficult Test Setup becomes much more difficult

Page 21: High Cohesion Low Coupling Old Standards for Object Oriented Programming

Interface Segregation PrincpleClients shouldn't be forced to

implement interfaces they don't use

Page 22: High Cohesion Low Coupling Old Standards for Object Oriented Programming

Interface Segregation PrincpleExample of FAT or Polluted

Interface Try implementing custom Membership Provider in ASP.NET 2.0.

You just need to implement 27 methods/properties

Page 23: High Cohesion Low Coupling Old Standards for Object Oriented Programming

Interface Segregation PrincpleInterface Idoor{

void Lock();void UnLock();bool IsOpen();

}Public Class Door : Idoor{

public void Lock() {}public void UnLock(){}bool IsOpen(){}

} <Demo>

Page 24: High Cohesion Low Coupling Old Standards for Object Oriented Programming

Interface Segregation PrincpleConsider 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>

Page 25: High Cohesion Low Coupling Old Standards for Object Oriented Programming

Interface Segregation PrincpleProblemAll type of door are not timed By adding Timeout into IDoor we are

polluting our interface

Page 26: High Cohesion Low Coupling Old Standards for Object Oriented Programming

Interface Segregation Princplepublic interface ITimerClient { void TimeOut(); }public class SecurityDoor : IDoor, ITimerClient {

public void TimeOut(){…….}

}

Page 27: High Cohesion Low Coupling Old Standards for Object Oriented Programming

Demeterclass 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

end end

Page 28: High Cohesion Low Coupling Old Standards for Object Oriented Programming

DemeterThe fix:class Wallet

attr_accessor :cash def withdraw(amount) raise InsufficientFundsError

if amount > cash cash -= amountamount

end end class Customer

has_one :wallet # behavior delegation def pay(amount)

@wallet.withdraw(amount) end

end class Paperboy

def collect_money(customer, due_amount) @collected_amount += customer.pay(due_amount)

end end

Page 29: High Cohesion Low Coupling Old Standards for Object Oriented Programming

Liskov Substitution PrincipleAll sub-classes must be substitutable for their

base class.

Page 30: High Cohesion Low Coupling Old Standards for Object Oriented Programming

Liskov violationStructural

You should not have to explicitly cast a base object to it’s subclass to do something.

BehaviorSubtypes should behave in a consistent manner

in terms of their clients

Page 31: High Cohesion Low Coupling Old Standards for Object Oriented Programming

Liskov Examplepublic class Customer{

FirstName{get;set}LastName{get;set}Order GetOrder()

}

public class PreferredCustomer : Customer{double GetDiscount()

}

//voilationforeach(Customer c in CustomerList){

if(c is PreferredCustomer){GetDiscount();

}}

Page 32: High Cohesion Low Coupling Old Standards for Object Oriented Programming

LiskovSubtypes should restrict the subclass, not

expand it.Use Composition to solve expansion

violations

Page 33: High Cohesion Low Coupling Old Standards for Object Oriented Programming

Bottom line …SRP

Only one reason to changeDIP

“Don’t call me, I’ll call you”OCP

Open for extension, Closed for modificationLSP

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

Page 34: High Cohesion Low Coupling Old Standards for Object Oriented Programming

Remember… Always code as if the guy

maintaining your code would be a violent psychopath and

he knows where you live.