Download presentation
Presentation is loading. Please wait.
Published byMoris Bridges Modified over 9 years ago
1
Lecture 13 Law of Demeter
2
Cohesion Cohesion: the “glue” that holds a module together. Don’t do things that do not support a common goal Cohesion: the “glue” that holds a module together. Don’t do things that do not support a common goal As with coupling there are degrees of cohesion As with coupling there are degrees of cohesion Listed from most to least desirable Listed from most to least desirable
3
Taxonomy of Cohesion Data Cohesion: A module implements a data abstraction Data Cohesion: A module implements a data abstraction Functional Cohesion: All elements are dedicated to performing a single function Functional Cohesion: All elements are dedicated to performing a single function Sequential Cohesion: Calling the elements in a specific order Sequential Cohesion: Calling the elements in a specific order Communication Cohesion: All elements operate on the same input/output data Communication Cohesion: All elements operate on the same input/output data
4
Taxonomy of Cohesion (ctd) Temporal Cohesion: Elements are invoked at or near the same time Temporal Cohesion: Elements are invoked at or near the same time Logical Cohesion: If tasks the elements perform are conceptually related Logical Cohesion: If tasks the elements perform are conceptually related Coincidental Cohesion: If the tasks the elements perform are totally unrelated Coincidental Cohesion: If the tasks the elements perform are totally unrelated
5
Functional Cohesion Elements perform tasks in a specific domain for a specific purpose Elements perform tasks in a specific domain for a specific purpose Meyers: “The purpose of an informational strength module is to hide some concept, data structure or resource in a single module” Meyers: “The purpose of an informational strength module is to hide some concept, data structure or resource in a single module” class bakeCake{ void addIngredients(){...} void mixBatter(){...} void bake(){...} }
6
Sequential Cohesion The output from one element becomes the input for another The output from one element becomes the input for another The previous example is sequentially cohesive, because the order and tasks performed are sequentially determined The previous example is sequentially cohesive, because the order and tasks performed are sequentially determined Bad for reusability and maintainability Bad for reusability and maintainability
7
Communication Cohesion Share portions of a common data structure or parameters Share portions of a common data structure or parameters Example:Calculate employee statistics and write monthly paycheck Example:Calculate employee statistics and write monthly paycheck Problems Problems Wide interface Bad reusability and maintenenace Cure: Isolate each sharing member into a separate module Cure: Isolate each sharing member into a separate module
8
Temporal Cohesion Tasks are performed at about the same time Tasks are performed at about the same time E.g. Initialize a program at boot time E.g. Initialize a program at boot time Main problem: Multiple functions, elements are not necessarily cohesive Main problem: Multiple functions, elements are not necessarily cohesive class initStuff{ void initMemory(){...} void initDisk(){...} void initPrinter{...} }
9
Logical Cohesion Tasks are conceptually related, but no data or control connection Tasks are conceptually related, but no data or control connection Problems: Problems: Wide Interface Multiple Functions class areaUtils{ double squareArea(){...} double triangArea(){...} double circleArea(){...} }
10
Coincidental Cohesion The worst kind: the “kitchen sink”. No real reason for grouping The worst kind: the “kitchen sink”. No real reason for grouping Big offender one-class Java Big offender one-class Java Problems: Problems: Multiple functionality Result of poor maintenance class myStuff{ void initPrinter(){...} double calculateTaxes(){...} Date getDate(){...}
11
Also: Procedural Cohesion Associate elements on the basis of algorithmic or procedural relationships Associate elements on the basis of algorithmic or procedural relationships First do A then B, hence put them together in one method or element First do A then B, hence put them together in one method or element class Stack{... public void push(){int addMe=readInt (“Type an int”); elements{++sp]=addMe;} public void pop(){int next=elements[SP--]; println(next);} }
12
Law of Demeter (LoD) Good technique for reducing coupling between objects in programming code Good technique for reducing coupling between objects in programming code Proven “Industrial Strength”. i.e. used in major SW projects to reduce maintenance costs Proven “Industrial Strength”. i.e. used in major SW projects to reduce maintenance costs Let’s look at an example Let’s look at an example
13
POST Project Consider a customer at check-out: Consider a customer at check-out: public class Customer{ private String firstName; private String lastName; private String myWallet; public String getFirstName(){return firstName;} public String getLastName(){return lastName;} public String getWallet(){ return myWallet:]
14
POST Project Now define a Wallet class: Now define a Wallet class: public class Wallet{ private float value; public float getTotalMoney(){return value;} public void setTotalMoney(float val){value = val;} public void addMoney(){float deposit){ value += deposit;} public void subtractMoney(float debit){ value -= debit;} }
15
POST Porject Now include some code from the Cashier class: Now include some code from the Cashier class: payment = 15.95 Wallet theWallet = myCustomer.getWallet(); if (theWallet.getTotalMoney()) >= payment){ theWallet.subtractMoney(payment);} else...
16
Why Is This Bad? Do you just want to give your wallet to the Cashier? The Cashier is exposed to more information than it actually needs Do you just want to give your wallet to the Cashier? The Cashier is exposed to more information than it actually needs The Cashier knows too much about the wallet and can manipulate it The Cashier knows too much about the wallet and can manipulate it The classes Customer, Wallet and Cashier are tightly coupled. If you change the Wallet class then a change to the other two is probably necessary. The classes Customer, Wallet and Cashier are tightly coupled. If you change the Wallet class then a change to the other two is probably necessary.
17
Try This What if the wallet was stolen in the store? Then call victim.setWallet(null); ? What if the wallet was stolen in the store? Then call victim.setWallet(null); ? Our code assumes a wallet, so you will get a runtime exception! If you check for null the code starts becoming complicated Our code assumes a wallet, so you will get a runtime exception! If you check for null the code starts becoming complicated Improvement: Rewrite the Customer class, throw out the getWallet() method, but put in a makePayment() Improvement: Rewrite the Customer class, throw out the getWallet() method, but put in a makePayment()
18
public class customer{... public float makePayment(float amount){ if (myWallet != null){ if (myWallet.getTotalMoney() >= amount){ myWallet.subtractMoney(amount); return amount;} else..... }
19
Conclusion Cashier doesn’t even know Customer has a Wallet !! Cashier doesn’t even know Customer has a Wallet !! Now use the Cashier code: Now use the Cashier code: payment = 15.95; paidUp = myCustomer.getPayment(payment); if(paidUp == payment) printReceipt(payment); else...
20
Why Is This Better? Fact: Customer has become more complex Fact: Customer has become more complex But, this is more realistic-- Cashier asks Customer for payment; Cashier has no direct access to the customer’s Wallet But, this is more realistic-- Cashier asks Customer for payment; Cashier has no direct access to the customer’s Wallet The class Wallet can now change and the Cashier detects no difference. The class Wallet can now change and the Cashier detects no difference. If the Wallet interface changed, then only Customer has to be updated. Code is easier to maintain Changes don’t ripple up
21
The Are Drawbacks Customer is more complex, i.e. has more methods Customer is more complex, i.e. has more methods But before Cashier needed to know about the Wallet, now not. Complexity has been reduced to where is belongs If, e.g. the Wallet had a credit card, then the method getCreditCardNumber(); returns the cc#, not the Wallet If, e.g. the Wallet had a credit card, then the method getCreditCardNumber(); returns the cc#, not the Wallet
22
LoD (weak version) Law of Demeter: A method of an object should only invoke methods from the following kind of objects Law of Demeter: A method of an object should only invoke methods from the following kind of objects itself its parameters any objects is creates its direct component objects Each object should have only a limited knowledge of other objects Each object should have only a limited knowledge of other objects
23
When and How to Apply Eliminate chained get -Statements: e.g. ccnr = person.getWallet().getccnr(); should be changed ccnr = person.getCCnr(); and let person worry about the ccnr. Eliminate chained get -Statements: e.g. ccnr = person.getWallet().getccnr(); should be changed ccnr = person.getCCnr(); and let person worry about the ccnr. Get rid of temps to do the chaining Get rid of temps to do the chaining Never import what you don’t need Never import what you don’t need
24
LoD (strong version) In addition to LoD, require In addition to LoD, require Never access data directly ininheritance-- always use accessors (i.e. gets and sets )
25
LoD and Design Patterns Most obvious: LoD implies delegation, because the complexity is put where it belongs Most obvious: LoD implies delegation, because the complexity is put where it belongs Adapter, Proxy and Decorator wrap objects and so force the user to a more suitable interface Adapter, Proxy and Decorator wrap objects and so force the user to a more suitable interface Facade hides other classes behind an API Facade hides other classes behind an API
Similar presentations
© 2024 SlidePlayer.com Inc.
All rights reserved.