SlideShare uma empresa Scribd logo
1 de 62
Baixar para ler offline
The Law Of Demeter
& objective sense of style
vladimir tsukur partner @
team &
tech lead @
Vladimir Tsukur / FOLLOW ME: twitter.com/flushdia or EMAIL TO: flushdia@gmail.com
Example:
Boy dating a girl
Example:Boy dating a girl
class Girl {
private List<GirlRoutine> schedule = new ArrayList<>();
List<GirlRoutine> getSchedule() {
return schedule;
}
}
class GirlRoutine {
private String description;
private Date startTime;
private Date endTime;
boolean happensAt(Date time) {
return time.after(startTime) && time.before(endTime);
}
}
Law of Demeter
Example:Boy dating a girl
class Boy {
private SoccerGame soccerGame;
boolean arrangeDate(Girl girl, Date time) {
if (soccerGame.at(time))) return false;
boolean success = true;
for (GirlRoutine routine : girl.getSchedule()) {
if (routine.happensAt(time)) {
success = false;
break; // my heart :(
}
}
return success;
}
}
Law of Demeter
class Boy {
private SoccerGame soccerGame;
boolean arrangeDate(Girl girl, Date time) {
if (soccerGame.at(time))) return false;
boolean success = true;
for (GirlRoutine routine : girl.getSchedule()) {
if (routine.happensAt(time)) {
success = false;
break; // my heart :(
}
}
return success;
}
}
Law of Demeter
WHY IS THIS BAD?
WHY IS THIS BAD?
class Boy {
...
boolean arrangeDate(Girl girl, Date time) {
...
...
for (GirlRoutine routine : girl.getSchedule()) {
if (routine.happensAt(time)) {
...
...
}
}
...
}
}
Law of Demeter
Why the hell should he look
at her schedule???
WHY IS THIS BAD?
class DecisionMaker {
...
boolean decide(Container container, Object param) {
...
...
for (Item item : container.getItems()) {
if (item.checkSomething(param)) {
...
...
}
}
...
}
}
Law of Demeter
Privacy!
technically
• Boy will require Girl and GirlRoutine
during compilation
• Changes in GirlRoutine will affect Boy
and Girl
=> Boy, Girl and GirlRoutine are tightly
coupled
(structural coupling)
Law of Demeter
Questions
• What if the list of routines is null?
• What if decision is not going to
depend on routines at all?
• What if mother or father would like to
check if their daughter is free?
Law of Demeter
Law of Demeter
Better Boy
class Boy {
private SoccerGame soccerGame;
boolean tryArrangeDate(Girl girl, Date time) {
return !soccerGame.at(time) && girl.freeAt(time);
}
}
Better Girl
class Girl {
private List<GirlRoutine> schedule = new ArrayList<>();
boolean freeAt(Date time) {
boolean free = true;
for (GirlRoutine routine : schedule) {
if (routine.happensAt(time)) {
free = false;
break;
}
}
return free;
}
}
Law of Demeter
benefits
• Better models real-world scenario
• GirlRoutine may change not affecting
Boy in any way
• Implementation of freeAt() method
may now change easily
Law of Demeter
law of
Law of Demeter
Ian Holland
1987
•oop design style
•aka principle of least knowledge
•specific case of loose coupling
•Introduced by:
demeter
Law of Demeter
goddess of the
harvest
« grow software
in small steps »
only talk to your
class Boy {
private SoccerGame soccerGame;
boolean arrangeDate(Girl girl, Date time) {
if (soccerGame.at(time))) return false;
boolean success = true;
for (GirlRoutine routine : girl.getSchedule()) {
if (routine.happensAt(time)) {
success = false;
break; // my heart :(
}
}
return success;
}
}
Law of Demeter
law of demeter
lod-f formally
• O itself
• m's parameters
• Any objects created within m
• O's direct component objects
Law of Demeter
Method m of an object O may only invoke the methods of
the following kinds of objects:
Law of Demeter
self: ALLOWED
class Boy {
private SoccerGame soccerGame;
boolean arrangeDate(Girl girl, Date time) {
return freeAt(time) && girl.freeAt(time);
}
boolean freeAt(Date time) {
return !soccerGame.at(time);
}
}
Law of Demeter
fields: ALLOWED
class Boy {
private SoccerGame soccerGame;
boolean arrangeDate(Girl girl, Date time) {
return freeAt(time) && girl.freeAt(time);
}
boolean freeAt(Date time) {
return !soccerGame.at(time);
}
}
Law of Demeter
parameters: ALLOWED
class Boy {
private SoccerGame soccerGame;
boolean arrangeDate(Girl girl, Date time) {
return freeAt(time) && girl.freeAt(time);
}
boolean freeAt(Date time) {
return !soccerGame.at(time);
}
}
class Girl {
boolean freeAt(Date time) {
return new Random().nextBoolean();
}
}
Law of Demeter
new objects: ALLOWED
class Girl {
private static final Girl BEST_FRIEND = ...;
boolean freeAt(Date time) {
return BEST_FRIEND.freeAt(time);
}
}
Law of Demeter
global context: ALLOWED
class Seller {
void sell(Client client, Product product) {
Wallet wallet = client.getWallet();
if (wallet.getMoney() > product.getPrice()) {
wallet.setMoney(wallet.getMoney() - product.getPrice());
}
else {
throw new NotEnoughMoneyException();
}
}
}
Law of Demeter
LOD: VIOLATION
getThis().getThat().
getSomethingElse().
doTheWork();
Law of Demeter
LOD: VIOLATION
immediate friends only!
Law of Demeter
BA C
positive implications
• Simplifies modifications
• Simplifies complexity of
programming
Law of Demeter
positive implications
• Less dependencies, loose
coupling =>
• Better maintainability
• Better reuse
• Less bugs
Law of Demeter
LOD &
unit tests
class PageSecurityService {
PageSecurityService(SecurityContext securityContext) { ... }
boolean checkAccess(User user, Page page) {
return !securityContext.getGlobalLock().isEnabled() &&
securityContext.getApplicationContext().
getSecurityDao().userHasPermission(user, page);
}
}
Law of Demeter
page security service
@Test
public void user_should_have_access_to_an_open_page() {
User user = new User("John");
Page page = new Page("/john/hangouts");
/* Prepare System Under Test (SUT). */
PageSecurityService sut = ...;
assertThat(sut.checkAccess(user, page), is(true));
}
Law of Demeter
unit test (Shell)
...
GlobalLock globalLock = mock(GlobalLock.class);
when(globalLock.isEnabled()).thenReturn(false);
SecurityDao securityDao = mock(SecurityDao.class);
when(securityDao.userHasPermission(user, page)).thenReturn(true);
ApplicationContext applicationContext = mock(ApplicationContext.class);
when(applicationContext.getSecurityDao()).thenReturn(securityDao);
SecurityContext securityContext = mock(SecurityContext.class);
when(securityContext.getGlobalLock()).thenReturn(globalLock);
when(securityContext.getApplicationContext()).thenReturn(applicationContext);
PageSecurityService sut = new PageSecurityService(securityContext);
...
Law of Demeter
unit test (SUT setup)
thanks no!
class PageSecurityService {
private final SecurityDao securityDao;
private final GlobalLock globalLock;
PageSecurityService(SecurityContext securityContext) {
securityDao = securityContext.getAppContext().getSecurityDao();
globalLock = securityContext.getGlobalLock();
}
...
boolean checkNonAuthenticatedAccess(Page page) {
return !globalLock.isEnabled() && page.isPublic();
}
}
Law of Demeter
put it to constructor?
even worse
class PageSecurityService {
PageSecurityService(GlobalLock aGlobalLock,
SecurityDao aSecurityDao) {
this.globalLock = aGlobalLock;
this.securityDao = aSecurityDao;
}
boolean hasAccessTo(User user, Page page) {
return !globalLock.isEnabled() &&
securityDao.userHasPermission(user, page);
}
}
Law of Demeter
better service
...
/* Prepare SecurityContext. */
GlobalLock globalLock = mock(GlobalLock.class);
when(globalLock.isEnabled()).thenReturn(false);
SecurityDao securityDao = mock(SecurityDao.class);
when(securityDao.userHasPermission(user, page)).thenReturn(true);
PageSecurityService sut =
new PageSecurityService(globalLock, securityDao);
...
Law of Demeter
unit test (SUT setup)
«shy» code
is beneficial
Law of Demeter
class PageSecurityService {
PageSecurityService(SecurityContext securityContext) { ... }
boolean hasAccessTo(User user, Page page) {
return !securityContext.getGlobalLock().isEnabled() &&
securityContext.getApplicationContext().
getSecurityDao().userHasPermission(user, page);
}
}
Law of Demeter
response for class
RFC = 7
violates lod
class PageSecurityService {
PageSecurityService(GlobalLock globalLock,
SecurityDao securityDao) { ... }
boolean hasAccessTo(User user, Page page) {
return !globalLock.isEnabled() &&
securityDao.userHasPermission(user, page);
}
}
Law of Demeter
response for class
RFC = 4
Satisfies lod
LAW OF DEMETER
=> (usually) Lower RFC
response for class
Study
WHAT?
Number of distinct methods
and constructors invoked by
a class
why bother?
The larger the RFC, the larger
the probability of fault
detection
0%
3%
6%
9%
12%
All New Ext DB UI
Law of Demeter
∆ψ[1]
[1] Basili, Victor; Briand, L.; Melo, W. L. (1996-10). http://www.cs.umd.edu/~basili/publications/journals/J62.pdf
class RedirectService {
void service(HttpServletRequest request,
HttpServletResponse response) throws IOException {
if («GET».equals(request.getMethod())) {
String uri = String.format("http://to.com%s?sessionId=%s",
request.getRequestURI(),
request.getSession(true).getId());
response.sendRedirect(uri);
}
}
}
Law of Demeter
weighted methods per class
WMC = 2
violates lod
class RedirectService {
void service(HttpServletRequest request,
HttpServletResponse response) throws IOException {
if («GET».equals(request.getMethod())) {
String uri = String.format("http://to.com%s?sessionId=%s",
request.getRequestURI(),
getSessionId(request.getSession()));
response.sendRedirect(uri);
}
}
private String getSessionId(HttpSession session) {
return session.getId();
}
}
Law of Demeter
weighted methods per class
WMC = 3
Satisfies lod
weighted methods per class
Study
WHAT?
The sum of the complexities
of all class methods
why bother?
The larger the WMC, the
larger the probability of fault
detection
0%
3%
6%
9%
12%
All New Ext DB UI
Law of Demeter
∆ψ[1]
[1] Basili, Victor; Briand, L.; Melo, W. L. (1996-10). http://www.cs.umd.edu/~basili/publications/journals/J62.pdf
law of demeter
Lower RFC
> (is more important than)
Higher WMC
Law of Demeter
0%
3%
6%
9%
12%
All New Ext DB UI
0%
3%
6%
9%
12%
All New Ext DB UI
Law of Demeter
bugs-LOD violations
correlation[1]
Title LOC SVLoD WVLoD
eclipse.jdt.core 0.76 0.67 0.59
eclipse.pde.core 0.64 0.61 0.61
eclipse.jface 0.82 0.73 0.67
eclipse.compare 0.62 0.43 0.42
eclipse.debug.core 0.72 0.7 0.62
Law of Demeter
[1] Yi guo, michael wursch, emanuel giger, harald c. gall, An Empirical Validation of the Benefits of
Adhering to the Law of Demeter (2011). http://www.ccs.neu.edu/home/lieber/LoD/LoD-2011-Zurich.pdf
Study
person.toString().toUpperCase()
Law of Demeter
violates lod but looks ok!
List<Number> collection = ...;
int value = collection.get(0).intValue();
Law of Demeter
violates lod but looks ok!
CustomerDTO customer = ...;
customer.getAddressDTO().getCountryDTO();
Law of Demeter
violates lod but looks ok!
Column column = builder.createColumn().
withId(«res»).
withName(«Resolution»).
build();
Law of Demeter
violates lod but looks ok!
Law of Demeter
use only one dot!
object.method()
BUT ...
column.
setId(«res»).
setName(«Resolution»);
Law of Demeter
looks ok!
follows lod-F but still SO-So
class Boy {
private SoccerGame soccerGame;
boolean arrangeDate(Girl girl, Date time) {
return !soccerGame.at(time) && girlIsFree(girl.getSchedule(), time);
}
private boolean girlIsFree(List<GirlRoutine> schedule, Date time) {
for (GirlRoutine routine : schedule) {
if (routineAt(routine, time)) return false;
}
return true;
}
private boolean routineAt(GirlRoutine routine, Date time) {
return routine.at(time);
}
}
Law of Demeter
law of
Law of Demeter
1. DRY
2. min method arguments
3. min methods per class
+
good style =
Law of Demeter
tooling
5.0 +
Questions?
At first sight
the idea of any rules or principles
being superimposed on the creative mind
seems more likely to hinder than to help, but
this is really quite untrue in practice.
Disciplined thinking focuses inspiratioN
rather than blinkers it[1]
Law of Demeter [1] Gordon l. glegg. "the design of design". cambridge university press. 1969

Mais conteúdo relacionado

Mais procurados

Mais procurados (20)

Design Patterns Presentation - Chetan Gole
Design Patterns Presentation -  Chetan GoleDesign Patterns Presentation -  Chetan Gole
Design Patterns Presentation - Chetan Gole
 
Code smell overview
Code smell overviewCode smell overview
Code smell overview
 
Observer Software Design Pattern
Observer Software Design Pattern Observer Software Design Pattern
Observer Software Design Pattern
 
Proxy design pattern (Class Ambassador)
Proxy design pattern (Class Ambassador)Proxy design pattern (Class Ambassador)
Proxy design pattern (Class Ambassador)
 
Facade Design Pattern
Facade Design PatternFacade Design Pattern
Facade Design Pattern
 
Abstract Factory Pattern
Abstract Factory PatternAbstract Factory Pattern
Abstract Factory Pattern
 
Design pattern-presentation
Design pattern-presentationDesign pattern-presentation
Design pattern-presentation
 
Builder pattern
Builder patternBuilder pattern
Builder pattern
 
Code smells and remedies
Code smells and remediesCode smells and remedies
Code smells and remedies
 
Adapter Design Pattern
Adapter Design PatternAdapter Design Pattern
Adapter Design Pattern
 
Proxy design pattern
Proxy design patternProxy design pattern
Proxy design pattern
 
Alice 8
Alice 8Alice 8
Alice 8
 
Factory Method Pattern
Factory Method PatternFactory Method Pattern
Factory Method Pattern
 
A Scala Corrections Library
A Scala Corrections LibraryA Scala Corrections Library
A Scala Corrections Library
 
Refactoring Tips by Martin Fowler
Refactoring Tips by Martin FowlerRefactoring Tips by Martin Fowler
Refactoring Tips by Martin Fowler
 
Introduction to design patterns
Introduction to design patternsIntroduction to design patterns
Introduction to design patterns
 
Flyweight pattern
Flyweight patternFlyweight pattern
Flyweight pattern
 
React hooks
React hooksReact hooks
React hooks
 
Greenfoot 10
Greenfoot 10Greenfoot 10
Greenfoot 10
 
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - with ...
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - with ...Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - with ...
Folding Unfolded - Polyglot FP for Fun and Profit - Haskell and Scala - with ...
 

Destaque

3 - Architetture Software - Architectural styles
3 - Architetture Software - Architectural styles3 - Architetture Software - Architectural styles
3 - Architetture Software - Architectural styles
Majong DevJfu
 

Destaque (8)

The Law of Demeter
The Law of DemeterThe Law of Demeter
The Law of Demeter
 
Software design principles
Software design principlesSoftware design principles
Software design principles
 
Software Architecture Taxonomies - Behaviour: Components & Connectors
Software Architecture Taxonomies - Behaviour: Components & ConnectorsSoftware Architecture Taxonomies - Behaviour: Components & Connectors
Software Architecture Taxonomies - Behaviour: Components & Connectors
 
Docker & JVM: A Perfect Match
Docker & JVM: A Perfect MatchDocker & JVM: A Perfect Match
Docker & JVM: A Perfect Match
 
Refactoring to Java 8 (QCon New York)
Refactoring to Java 8 (QCon New York)Refactoring to Java 8 (QCon New York)
Refactoring to Java 8 (QCon New York)
 
3 - Architetture Software - Architectural styles
3 - Architetture Software - Architectural styles3 - Architetture Software - Architectural styles
3 - Architetture Software - Architectural styles
 
Principles of software architecture design
Principles of software architecture designPrinciples of software architecture design
Principles of software architecture design
 
Software Architecture: Styles
Software Architecture: StylesSoftware Architecture: Styles
Software Architecture: Styles
 

Semelhante a Law of Demeter & Objective Sense of Style

AST Transformations at JFokus
AST Transformations at JFokusAST Transformations at JFokus
AST Transformations at JFokus
HamletDRC
 
名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン
名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン
名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン
Tsuyoshi Yamamoto
 

Semelhante a Law of Demeter & Objective Sense of Style (6)

AST Transformations at JFokus
AST Transformations at JFokusAST Transformations at JFokus
AST Transformations at JFokus
 
C# - A Programmer's Dream Come True
C# - A Programmer's Dream Come TrueC# - A Programmer's Dream Come True
C# - A Programmer's Dream Come True
 
JDD2015: Where Test Doubles can lead you... - Sebastian Malaca
JDD2015: Where Test Doubles can lead you...  - Sebastian Malaca JDD2015: Where Test Doubles can lead you...  - Sebastian Malaca
JDD2015: Where Test Doubles can lead you... - Sebastian Malaca
 
From typing the test to testing the type
From typing the test to testing the typeFrom typing the test to testing the type
From typing the test to testing the type
 
Broken windows de práticas ágeis
Broken windows de práticas ágeisBroken windows de práticas ágeis
Broken windows de práticas ágeis
 
名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン
名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン
名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン
 

Mais de Vladimir Tsukur

Abstraction Classes in Software Design
Abstraction Classes in Software DesignAbstraction Classes in Software Design
Abstraction Classes in Software Design
Vladimir Tsukur
 
Acceptance Testing of Web UI
Acceptance Testing of Web UIAcceptance Testing of Web UI
Acceptance Testing of Web UI
Vladimir Tsukur
 
REpresentational State Transfer
REpresentational State TransferREpresentational State Transfer
REpresentational State Transfer
Vladimir Tsukur
 

Mais de Vladimir Tsukur (12)

GraphQL APIs in Scala with Sangria
GraphQL APIs in Scala with SangriaGraphQL APIs in Scala with Sangria
GraphQL APIs in Scala with Sangria
 
GraphQL - APIs The New Way
GraphQL - APIs The New WayGraphQL - APIs The New Way
GraphQL - APIs The New Way
 
Hypermedia APIs and HATEOAS / Wix Engineering
Hypermedia APIs and HATEOAS / Wix EngineeringHypermedia APIs and HATEOAS / Wix Engineering
Hypermedia APIs and HATEOAS / Wix Engineering
 
Hypermedia APIs and HATEOAS
Hypermedia APIs and HATEOASHypermedia APIs and HATEOAS
Hypermedia APIs and HATEOAS
 
Hot and spicy Java with Lombok. Live!
Hot and spicy Java with Lombok. Live!Hot and spicy Java with Lombok. Live!
Hot and spicy Java with Lombok. Live!
 
Building Awesome API with Spring
Building Awesome API with SpringBuilding Awesome API with Spring
Building Awesome API with Spring
 
From CRUD to Hypermedia APIs with Spring
From CRUD to Hypermedia APIs with SpringFrom CRUD to Hypermedia APIs with Spring
From CRUD to Hypermedia APIs with Spring
 
Together Cheerfully to Walk with Hypermedia
Together Cheerfully to Walk with HypermediaTogether Cheerfully to Walk with Hypermedia
Together Cheerfully to Walk with Hypermedia
 
Take a REST!
Take a REST!Take a REST!
Take a REST!
 
Abstraction Classes in Software Design
Abstraction Classes in Software DesignAbstraction Classes in Software Design
Abstraction Classes in Software Design
 
Acceptance Testing of Web UI
Acceptance Testing of Web UIAcceptance Testing of Web UI
Acceptance Testing of Web UI
 
REpresentational State Transfer
REpresentational State TransferREpresentational State Transfer
REpresentational State Transfer
 

Último

CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
giselly40
 

Último (20)

GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 

Law of Demeter & Objective Sense of Style

  • 1. The Law Of Demeter & objective sense of style
  • 2. vladimir tsukur partner @ team & tech lead @ Vladimir Tsukur / FOLLOW ME: twitter.com/flushdia or EMAIL TO: flushdia@gmail.com
  • 4. Example:Boy dating a girl class Girl { private List<GirlRoutine> schedule = new ArrayList<>(); List<GirlRoutine> getSchedule() { return schedule; } } class GirlRoutine { private String description; private Date startTime; private Date endTime; boolean happensAt(Date time) { return time.after(startTime) && time.before(endTime); } } Law of Demeter
  • 5. Example:Boy dating a girl class Boy { private SoccerGame soccerGame; boolean arrangeDate(Girl girl, Date time) { if (soccerGame.at(time))) return false; boolean success = true; for (GirlRoutine routine : girl.getSchedule()) { if (routine.happensAt(time)) { success = false; break; // my heart :( } } return success; } } Law of Demeter
  • 6. class Boy { private SoccerGame soccerGame; boolean arrangeDate(Girl girl, Date time) { if (soccerGame.at(time))) return false; boolean success = true; for (GirlRoutine routine : girl.getSchedule()) { if (routine.happensAt(time)) { success = false; break; // my heart :( } } return success; } } Law of Demeter WHY IS THIS BAD?
  • 7. WHY IS THIS BAD? class Boy { ... boolean arrangeDate(Girl girl, Date time) { ... ... for (GirlRoutine routine : girl.getSchedule()) { if (routine.happensAt(time)) { ... ... } } ... } } Law of Demeter Why the hell should he look at her schedule???
  • 8. WHY IS THIS BAD? class DecisionMaker { ... boolean decide(Container container, Object param) { ... ... for (Item item : container.getItems()) { if (item.checkSomething(param)) { ... ... } } ... } } Law of Demeter
  • 10. technically • Boy will require Girl and GirlRoutine during compilation • Changes in GirlRoutine will affect Boy and Girl => Boy, Girl and GirlRoutine are tightly coupled (structural coupling) Law of Demeter
  • 11. Questions • What if the list of routines is null? • What if decision is not going to depend on routines at all? • What if mother or father would like to check if their daughter is free? Law of Demeter
  • 12. Law of Demeter Better Boy class Boy { private SoccerGame soccerGame; boolean tryArrangeDate(Girl girl, Date time) { return !soccerGame.at(time) && girl.freeAt(time); } }
  • 13. Better Girl class Girl { private List<GirlRoutine> schedule = new ArrayList<>(); boolean freeAt(Date time) { boolean free = true; for (GirlRoutine routine : schedule) { if (routine.happensAt(time)) { free = false; break; } } return free; } } Law of Demeter
  • 14. benefits • Better models real-world scenario • GirlRoutine may change not affecting Boy in any way • Implementation of freeAt() method may now change easily Law of Demeter
  • 15. law of Law of Demeter Ian Holland 1987 •oop design style •aka principle of least knowledge •specific case of loose coupling •Introduced by:
  • 17. « grow software in small steps »
  • 18.
  • 19. only talk to your
  • 20. class Boy { private SoccerGame soccerGame; boolean arrangeDate(Girl girl, Date time) { if (soccerGame.at(time))) return false; boolean success = true; for (GirlRoutine routine : girl.getSchedule()) { if (routine.happensAt(time)) { success = false; break; // my heart :( } } return success; } } Law of Demeter law of demeter
  • 21. lod-f formally • O itself • m's parameters • Any objects created within m • O's direct component objects Law of Demeter Method m of an object O may only invoke the methods of the following kinds of objects:
  • 22. Law of Demeter self: ALLOWED class Boy { private SoccerGame soccerGame; boolean arrangeDate(Girl girl, Date time) { return freeAt(time) && girl.freeAt(time); } boolean freeAt(Date time) { return !soccerGame.at(time); } }
  • 23. Law of Demeter fields: ALLOWED class Boy { private SoccerGame soccerGame; boolean arrangeDate(Girl girl, Date time) { return freeAt(time) && girl.freeAt(time); } boolean freeAt(Date time) { return !soccerGame.at(time); } }
  • 24. Law of Demeter parameters: ALLOWED class Boy { private SoccerGame soccerGame; boolean arrangeDate(Girl girl, Date time) { return freeAt(time) && girl.freeAt(time); } boolean freeAt(Date time) { return !soccerGame.at(time); } }
  • 25. class Girl { boolean freeAt(Date time) { return new Random().nextBoolean(); } } Law of Demeter new objects: ALLOWED
  • 26. class Girl { private static final Girl BEST_FRIEND = ...; boolean freeAt(Date time) { return BEST_FRIEND.freeAt(time); } } Law of Demeter global context: ALLOWED
  • 27. class Seller { void sell(Client client, Product product) { Wallet wallet = client.getWallet(); if (wallet.getMoney() > product.getPrice()) { wallet.setMoney(wallet.getMoney() - product.getPrice()); } else { throw new NotEnoughMoneyException(); } } } Law of Demeter LOD: VIOLATION
  • 29. immediate friends only! Law of Demeter BA C
  • 30. positive implications • Simplifies modifications • Simplifies complexity of programming Law of Demeter
  • 31. positive implications • Less dependencies, loose coupling => • Better maintainability • Better reuse • Less bugs Law of Demeter
  • 33. class PageSecurityService { PageSecurityService(SecurityContext securityContext) { ... } boolean checkAccess(User user, Page page) { return !securityContext.getGlobalLock().isEnabled() && securityContext.getApplicationContext(). getSecurityDao().userHasPermission(user, page); } } Law of Demeter page security service
  • 34. @Test public void user_should_have_access_to_an_open_page() { User user = new User("John"); Page page = new Page("/john/hangouts"); /* Prepare System Under Test (SUT). */ PageSecurityService sut = ...; assertThat(sut.checkAccess(user, page), is(true)); } Law of Demeter unit test (Shell)
  • 35. ... GlobalLock globalLock = mock(GlobalLock.class); when(globalLock.isEnabled()).thenReturn(false); SecurityDao securityDao = mock(SecurityDao.class); when(securityDao.userHasPermission(user, page)).thenReturn(true); ApplicationContext applicationContext = mock(ApplicationContext.class); when(applicationContext.getSecurityDao()).thenReturn(securityDao); SecurityContext securityContext = mock(SecurityContext.class); when(securityContext.getGlobalLock()).thenReturn(globalLock); when(securityContext.getApplicationContext()).thenReturn(applicationContext); PageSecurityService sut = new PageSecurityService(securityContext); ... Law of Demeter unit test (SUT setup)
  • 37. class PageSecurityService { private final SecurityDao securityDao; private final GlobalLock globalLock; PageSecurityService(SecurityContext securityContext) { securityDao = securityContext.getAppContext().getSecurityDao(); globalLock = securityContext.getGlobalLock(); } ... boolean checkNonAuthenticatedAccess(Page page) { return !globalLock.isEnabled() && page.isPublic(); } } Law of Demeter put it to constructor? even worse
  • 38. class PageSecurityService { PageSecurityService(GlobalLock aGlobalLock, SecurityDao aSecurityDao) { this.globalLock = aGlobalLock; this.securityDao = aSecurityDao; } boolean hasAccessTo(User user, Page page) { return !globalLock.isEnabled() && securityDao.userHasPermission(user, page); } } Law of Demeter better service
  • 39. ... /* Prepare SecurityContext. */ GlobalLock globalLock = mock(GlobalLock.class); when(globalLock.isEnabled()).thenReturn(false); SecurityDao securityDao = mock(SecurityDao.class); when(securityDao.userHasPermission(user, page)).thenReturn(true); PageSecurityService sut = new PageSecurityService(globalLock, securityDao); ... Law of Demeter unit test (SUT setup)
  • 42. class PageSecurityService { PageSecurityService(SecurityContext securityContext) { ... } boolean hasAccessTo(User user, Page page) { return !securityContext.getGlobalLock().isEnabled() && securityContext.getApplicationContext(). getSecurityDao().userHasPermission(user, page); } } Law of Demeter response for class RFC = 7 violates lod
  • 43. class PageSecurityService { PageSecurityService(GlobalLock globalLock, SecurityDao securityDao) { ... } boolean hasAccessTo(User user, Page page) { return !globalLock.isEnabled() && securityDao.userHasPermission(user, page); } } Law of Demeter response for class RFC = 4 Satisfies lod
  • 44. LAW OF DEMETER => (usually) Lower RFC
  • 45. response for class Study WHAT? Number of distinct methods and constructors invoked by a class why bother? The larger the RFC, the larger the probability of fault detection 0% 3% 6% 9% 12% All New Ext DB UI Law of Demeter ∆ψ[1] [1] Basili, Victor; Briand, L.; Melo, W. L. (1996-10). http://www.cs.umd.edu/~basili/publications/journals/J62.pdf
  • 46. class RedirectService { void service(HttpServletRequest request, HttpServletResponse response) throws IOException { if («GET».equals(request.getMethod())) { String uri = String.format("http://to.com%s?sessionId=%s", request.getRequestURI(), request.getSession(true).getId()); response.sendRedirect(uri); } } } Law of Demeter weighted methods per class WMC = 2 violates lod
  • 47. class RedirectService { void service(HttpServletRequest request, HttpServletResponse response) throws IOException { if («GET».equals(request.getMethod())) { String uri = String.format("http://to.com%s?sessionId=%s", request.getRequestURI(), getSessionId(request.getSession())); response.sendRedirect(uri); } } private String getSessionId(HttpSession session) { return session.getId(); } } Law of Demeter weighted methods per class WMC = 3 Satisfies lod
  • 48. weighted methods per class Study WHAT? The sum of the complexities of all class methods why bother? The larger the WMC, the larger the probability of fault detection 0% 3% 6% 9% 12% All New Ext DB UI Law of Demeter ∆ψ[1] [1] Basili, Victor; Briand, L.; Melo, W. L. (1996-10). http://www.cs.umd.edu/~basili/publications/journals/J62.pdf
  • 49. law of demeter Lower RFC > (is more important than) Higher WMC Law of Demeter 0% 3% 6% 9% 12% All New Ext DB UI 0% 3% 6% 9% 12% All New Ext DB UI
  • 51. bugs-LOD violations correlation[1] Title LOC SVLoD WVLoD eclipse.jdt.core 0.76 0.67 0.59 eclipse.pde.core 0.64 0.61 0.61 eclipse.jface 0.82 0.73 0.67 eclipse.compare 0.62 0.43 0.42 eclipse.debug.core 0.72 0.7 0.62 Law of Demeter [1] Yi guo, michael wursch, emanuel giger, harald c. gall, An Empirical Validation of the Benefits of Adhering to the Law of Demeter (2011). http://www.ccs.neu.edu/home/lieber/LoD/LoD-2011-Zurich.pdf Study
  • 53. List<Number> collection = ...; int value = collection.get(0).intValue(); Law of Demeter violates lod but looks ok!
  • 54. CustomerDTO customer = ...; customer.getAddressDTO().getCountryDTO(); Law of Demeter violates lod but looks ok!
  • 55. Column column = builder.createColumn(). withId(«res»). withName(«Resolution»). build(); Law of Demeter violates lod but looks ok!
  • 56. Law of Demeter use only one dot! object.method() BUT ...
  • 58. follows lod-F but still SO-So class Boy { private SoccerGame soccerGame; boolean arrangeDate(Girl girl, Date time) { return !soccerGame.at(time) && girlIsFree(girl.getSchedule(), time); } private boolean girlIsFree(List<GirlRoutine> schedule, Date time) { for (GirlRoutine routine : schedule) { if (routineAt(routine, time)) return false; } return true; } private boolean routineAt(GirlRoutine routine, Date time) { return routine.at(time); } } Law of Demeter
  • 59. law of Law of Demeter 1. DRY 2. min method arguments 3. min methods per class + good style =
  • 62. At first sight the idea of any rules or principles being superimposed on the creative mind seems more likely to hinder than to help, but this is really quite untrue in practice. Disciplined thinking focuses inspiratioN rather than blinkers it[1] Law of Demeter [1] Gordon l. glegg. "the design of design". cambridge university press. 1969