SlideShare a Scribd company logo
1 of 62
Download to read 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 »
Law of Demeter & Objective Sense of Style
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

More Related Content

What's hot

Dependency injection presentation
Dependency injection presentationDependency injection presentation
Dependency injection presentationAhasanul Kalam Akib
 
PHP para Adultos: Clean Code e Object Calisthenics
PHP para Adultos: Clean Code e Object CalisthenicsPHP para Adultos: Clean Code e Object Calisthenics
PHP para Adultos: Clean Code e Object CalisthenicsGuilherme Blanco
 
Kata: Hexagonal Architecture / Ports and Adapters
Kata: Hexagonal Architecture / Ports and AdaptersKata: Hexagonal Architecture / Ports and Adapters
Kata: Hexagonal Architecture / Ports and Adaptersholsky
 
Firebase & SwiftUI Workshop
Firebase & SwiftUI WorkshopFirebase & SwiftUI Workshop
Firebase & SwiftUI WorkshopPeter Friese
 
Mysql Crud, Php Mysql, php, sql
Mysql Crud, Php Mysql, php, sqlMysql Crud, Php Mysql, php, sql
Mysql Crud, Php Mysql, php, sqlAimal Miakhel
 
[2022]NaverMeetup_[Flutter] Dependency Injection과 Service Locator_임태규.pdf
[2022]NaverMeetup_[Flutter] Dependency Injection과 Service Locator_임태규.pdf[2022]NaverMeetup_[Flutter] Dependency Injection과 Service Locator_임태규.pdf
[2022]NaverMeetup_[Flutter] Dependency Injection과 Service Locator_임태규.pdfTaekyu Lim
 
JavaScript - Chapter 8 - Objects
 JavaScript - Chapter 8 - Objects JavaScript - Chapter 8 - Objects
JavaScript - Chapter 8 - ObjectsWebStackAcademy
 
Class and Objects in PHP
Class and Objects in PHPClass and Objects in PHP
Class and Objects in PHPRamasubbu .P
 
JavaScript - Chapter 12 - Document Object Model
  JavaScript - Chapter 12 - Document Object Model  JavaScript - Chapter 12 - Document Object Model
JavaScript - Chapter 12 - Document Object ModelWebStackAcademy
 
SOLID principles with Typescript examples
SOLID principles with Typescript examplesSOLID principles with Typescript examples
SOLID principles with Typescript examplesAndrew Nester
 
Google mock for dummies
Google mock for dummiesGoogle mock for dummies
Google mock for dummiesTony Nguyen
 
New methods for exploiting ORM injections in Java applications
New methods for exploiting ORM injections in Java applicationsNew methods for exploiting ORM injections in Java applications
New methods for exploiting ORM injections in Java applicationsMikhail Egorov
 

What's hot (20)

Dependency injection presentation
Dependency injection presentationDependency injection presentation
Dependency injection presentation
 
Clean coding-practices
Clean coding-practicesClean coding-practices
Clean coding-practices
 
Clean Code na Prática
Clean Code na PráticaClean Code na Prática
Clean Code na Prática
 
PHP para Adultos: Clean Code e Object Calisthenics
PHP para Adultos: Clean Code e Object CalisthenicsPHP para Adultos: Clean Code e Object Calisthenics
PHP para Adultos: Clean Code e Object Calisthenics
 
C#
C#C#
C#
 
Kata: Hexagonal Architecture / Ports and Adapters
Kata: Hexagonal Architecture / Ports and AdaptersKata: Hexagonal Architecture / Ports and Adapters
Kata: Hexagonal Architecture / Ports and Adapters
 
Firebase & SwiftUI Workshop
Firebase & SwiftUI WorkshopFirebase & SwiftUI Workshop
Firebase & SwiftUI Workshop
 
Clean code slide
Clean code slideClean code slide
Clean code slide
 
Clean code
Clean codeClean code
Clean code
 
Mysql Crud, Php Mysql, php, sql
Mysql Crud, Php Mysql, php, sqlMysql Crud, Php Mysql, php, sql
Mysql Crud, Php Mysql, php, sql
 
SOLID PRINCIPLES
SOLID PRINCIPLESSOLID PRINCIPLES
SOLID PRINCIPLES
 
[2022]NaverMeetup_[Flutter] Dependency Injection과 Service Locator_임태규.pdf
[2022]NaverMeetup_[Flutter] Dependency Injection과 Service Locator_임태규.pdf[2022]NaverMeetup_[Flutter] Dependency Injection과 Service Locator_임태규.pdf
[2022]NaverMeetup_[Flutter] Dependency Injection과 Service Locator_임태규.pdf
 
JavaScript - Chapter 8 - Objects
 JavaScript - Chapter 8 - Objects JavaScript - Chapter 8 - Objects
JavaScript - Chapter 8 - Objects
 
Class and Objects in PHP
Class and Objects in PHPClass and Objects in PHP
Class and Objects in PHP
 
JavaScript - Chapter 12 - Document Object Model
  JavaScript - Chapter 12 - Document Object Model  JavaScript - Chapter 12 - Document Object Model
JavaScript - Chapter 12 - Document Object Model
 
Asp.net mvc
Asp.net mvcAsp.net mvc
Asp.net mvc
 
SOLID principles with Typescript examples
SOLID principles with Typescript examplesSOLID principles with Typescript examples
SOLID principles with Typescript examples
 
Google mock for dummies
Google mock for dummiesGoogle mock for dummies
Google mock for dummies
 
Clean Code
Clean CodeClean Code
Clean Code
 
New methods for exploiting ORM injections in Java applications
New methods for exploiting ORM injections in Java applicationsNew methods for exploiting ORM injections in Java applications
New methods for exploiting ORM injections in Java applications
 

Viewers also liked

Software design principles
Software design principlesSoftware design principles
Software design principlesMd.Mojibul Hoque
 
Software Architecture Taxonomies - Behaviour: Components & Connectors
Software Architecture Taxonomies - Behaviour: Components & ConnectorsSoftware Architecture Taxonomies - Behaviour: Components & Connectors
Software Architecture Taxonomies - Behaviour: Components & ConnectorsJose Emilio Labra Gayo
 
Docker & JVM: A Perfect Match
Docker & JVM: A Perfect MatchDocker & JVM: A Perfect Match
Docker & JVM: A Perfect MatchMatthias Grüter
 
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)Trisha Gee
 
3 - Architetture Software - Architectural styles
3 - Architetture Software - Architectural styles3 - Architetture Software - Architectural styles
3 - Architetture Software - Architectural stylesMajong DevJfu
 
Principles of software architecture design
Principles of software architecture designPrinciples of software architecture design
Principles of software architecture designLen Bass
 
Software Architecture: Styles
Software Architecture: StylesSoftware Architecture: Styles
Software Architecture: StylesHenry Muccini
 

Viewers also liked (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
 

Similar to Law of Demeter & Objective Sense of Style

AST Transformations at JFokus
AST Transformations at JFokusAST Transformations at JFokus
AST Transformations at JFokusHamletDRC
 
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 TrueAlexander Pacha
 
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 PROIDEA
 
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 typeWim Godden
 
Broken windows de práticas ágeis
Broken windows de práticas ágeisBroken windows de práticas ágeis
Broken windows de práticas ágeisCecilia Fernandes
 
名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン
名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン名古屋SGGAE/J勉強会 Grails、Gaelykでハンズオン
名古屋SGGAE/J勉強会 Grails、GaelykでハンズオンTsuyoshi Yamamoto
 

Similar to 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でハンズオン
 

More from Vladimir Tsukur

GraphQL APIs in Scala with Sangria
GraphQL APIs in Scala with SangriaGraphQL APIs in Scala with Sangria
GraphQL APIs in Scala with SangriaVladimir Tsukur
 
GraphQL - APIs The New Way
GraphQL - APIs The New WayGraphQL - APIs The New Way
GraphQL - APIs The New WayVladimir Tsukur
 
Hypermedia APIs and HATEOAS / Wix Engineering
Hypermedia APIs and HATEOAS / Wix EngineeringHypermedia APIs and HATEOAS / Wix Engineering
Hypermedia APIs and HATEOAS / Wix EngineeringVladimir Tsukur
 
Hypermedia APIs and HATEOAS
Hypermedia APIs and HATEOASHypermedia APIs and HATEOAS
Hypermedia APIs and HATEOASVladimir Tsukur
 
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!Vladimir Tsukur
 
Building Awesome API with Spring
Building Awesome API with SpringBuilding Awesome API with Spring
Building Awesome API with SpringVladimir Tsukur
 
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 SpringVladimir Tsukur
 
Together Cheerfully to Walk with Hypermedia
Together Cheerfully to Walk with HypermediaTogether Cheerfully to Walk with Hypermedia
Together Cheerfully to Walk with HypermediaVladimir Tsukur
 
Abstraction Classes in Software Design
Abstraction Classes in Software DesignAbstraction Classes in Software Design
Abstraction Classes in Software DesignVladimir Tsukur
 
Acceptance Testing of Web UI
Acceptance Testing of Web UIAcceptance Testing of Web UI
Acceptance Testing of Web UIVladimir Tsukur
 
REpresentational State Transfer
REpresentational State TransferREpresentational State Transfer
REpresentational State TransferVladimir Tsukur
 

More from 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
 

Recently uploaded

Webinar: The Art of Prioritizing Your Product Roadmap by AWS Sr PM - Tech
Webinar: The Art of Prioritizing Your Product Roadmap by AWS Sr PM - TechWebinar: The Art of Prioritizing Your Product Roadmap by AWS Sr PM - Tech
Webinar: The Art of Prioritizing Your Product Roadmap by AWS Sr PM - TechProduct School
 
AI Workshops at Computers In Libraries 2024
AI Workshops at Computers In Libraries 2024AI Workshops at Computers In Libraries 2024
AI Workshops at Computers In Libraries 2024Brian Pichman
 
Q4 2023 Quarterly Investor Presentation - FINAL - v1.pdf
Q4 2023 Quarterly Investor Presentation - FINAL - v1.pdfQ4 2023 Quarterly Investor Presentation - FINAL - v1.pdf
Q4 2023 Quarterly Investor Presentation - FINAL - v1.pdfTejal81
 
SIM INFORMATION SYSTEM: REVOLUTIONIZING DATA MANAGEMENT
SIM INFORMATION SYSTEM: REVOLUTIONIZING DATA MANAGEMENTSIM INFORMATION SYSTEM: REVOLUTIONIZING DATA MANAGEMENT
SIM INFORMATION SYSTEM: REVOLUTIONIZING DATA MANAGEMENTxtailishbaloch
 
UiPath Studio Web workshop series - Day 1
UiPath Studio Web workshop series  - Day 1UiPath Studio Web workshop series  - Day 1
UiPath Studio Web workshop series - Day 1DianaGray10
 
Key Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfKey Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfCheryl Hung
 
Technical SEO for Improved Accessibility WTS FEST
Technical SEO for Improved Accessibility  WTS FESTTechnical SEO for Improved Accessibility  WTS FEST
Technical SEO for Improved Accessibility WTS FESTBillieHyde
 
.NET 8 ChatBot with Azure OpenAI Services.pptx
.NET 8 ChatBot with Azure OpenAI Services.pptx.NET 8 ChatBot with Azure OpenAI Services.pptx
.NET 8 ChatBot with Azure OpenAI Services.pptxHansamali Gamage
 
Automation Ops Series: Session 2 - Governance for UiPath projects
Automation Ops Series: Session 2 - Governance for UiPath projectsAutomation Ops Series: Session 2 - Governance for UiPath projects
Automation Ops Series: Session 2 - Governance for UiPath projectsDianaGray10
 
20140402 - Smart house demo kit
20140402 - Smart house demo kit20140402 - Smart house demo kit
20140402 - Smart house demo kitJamie (Taka) Wang
 
Planetek Italia Srl - Corporate Profile Brochure
Planetek Italia Srl - Corporate Profile BrochurePlanetek Italia Srl - Corporate Profile Brochure
Planetek Italia Srl - Corporate Profile BrochurePlanetek Italia Srl
 
How to become a GDSC Lead GDSC MI AOE.pptx
How to become a GDSC Lead GDSC MI AOE.pptxHow to become a GDSC Lead GDSC MI AOE.pptx
How to become a GDSC Lead GDSC MI AOE.pptxKaustubhBhavsar6
 
3 Pitfalls Everyone Should Avoid with Cloud Data
3 Pitfalls Everyone Should Avoid with Cloud Data3 Pitfalls Everyone Should Avoid with Cloud Data
3 Pitfalls Everyone Should Avoid with Cloud DataEric D. Schabell
 
EMEA What is ThousandEyes? Webinar
EMEA What is ThousandEyes? WebinarEMEA What is ThousandEyes? Webinar
EMEA What is ThousandEyes? WebinarThousandEyes
 
My key hands-on projects in Quantum, and QAI
My key hands-on projects in Quantum, and QAIMy key hands-on projects in Quantum, and QAI
My key hands-on projects in Quantum, and QAIVijayananda Mohire
 
Top 10 Squarespace Development Companies
Top 10 Squarespace Development CompaniesTop 10 Squarespace Development Companies
Top 10 Squarespace Development CompaniesTopCSSGallery
 
Explore the UiPath Community and ways you can benefit on your journey to auto...
Explore the UiPath Community and ways you can benefit on your journey to auto...Explore the UiPath Community and ways you can benefit on your journey to auto...
Explore the UiPath Community and ways you can benefit on your journey to auto...DianaGray10
 
TrustArc Webinar - How to Live in a Post Third-Party Cookie World
TrustArc Webinar - How to Live in a Post Third-Party Cookie WorldTrustArc Webinar - How to Live in a Post Third-Party Cookie World
TrustArc Webinar - How to Live in a Post Third-Party Cookie WorldTrustArc
 
Introduction - IPLOOK NETWORKS CO., LTD.
Introduction - IPLOOK NETWORKS CO., LTD.Introduction - IPLOOK NETWORKS CO., LTD.
Introduction - IPLOOK NETWORKS CO., LTD.IPLOOK Networks
 
2024.03.12 Cost drivers of cultivated meat production.pdf
2024.03.12 Cost drivers of cultivated meat production.pdf2024.03.12 Cost drivers of cultivated meat production.pdf
2024.03.12 Cost drivers of cultivated meat production.pdfThe Good Food Institute
 

Recently uploaded (20)

Webinar: The Art of Prioritizing Your Product Roadmap by AWS Sr PM - Tech
Webinar: The Art of Prioritizing Your Product Roadmap by AWS Sr PM - TechWebinar: The Art of Prioritizing Your Product Roadmap by AWS Sr PM - Tech
Webinar: The Art of Prioritizing Your Product Roadmap by AWS Sr PM - Tech
 
AI Workshops at Computers In Libraries 2024
AI Workshops at Computers In Libraries 2024AI Workshops at Computers In Libraries 2024
AI Workshops at Computers In Libraries 2024
 
Q4 2023 Quarterly Investor Presentation - FINAL - v1.pdf
Q4 2023 Quarterly Investor Presentation - FINAL - v1.pdfQ4 2023 Quarterly Investor Presentation - FINAL - v1.pdf
Q4 2023 Quarterly Investor Presentation - FINAL - v1.pdf
 
SIM INFORMATION SYSTEM: REVOLUTIONIZING DATA MANAGEMENT
SIM INFORMATION SYSTEM: REVOLUTIONIZING DATA MANAGEMENTSIM INFORMATION SYSTEM: REVOLUTIONIZING DATA MANAGEMENT
SIM INFORMATION SYSTEM: REVOLUTIONIZING DATA MANAGEMENT
 
UiPath Studio Web workshop series - Day 1
UiPath Studio Web workshop series  - Day 1UiPath Studio Web workshop series  - Day 1
UiPath Studio Web workshop series - Day 1
 
Key Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfKey Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdf
 
Technical SEO for Improved Accessibility WTS FEST
Technical SEO for Improved Accessibility  WTS FESTTechnical SEO for Improved Accessibility  WTS FEST
Technical SEO for Improved Accessibility WTS FEST
 
.NET 8 ChatBot with Azure OpenAI Services.pptx
.NET 8 ChatBot with Azure OpenAI Services.pptx.NET 8 ChatBot with Azure OpenAI Services.pptx
.NET 8 ChatBot with Azure OpenAI Services.pptx
 
Automation Ops Series: Session 2 - Governance for UiPath projects
Automation Ops Series: Session 2 - Governance for UiPath projectsAutomation Ops Series: Session 2 - Governance for UiPath projects
Automation Ops Series: Session 2 - Governance for UiPath projects
 
20140402 - Smart house demo kit
20140402 - Smart house demo kit20140402 - Smart house demo kit
20140402 - Smart house demo kit
 
Planetek Italia Srl - Corporate Profile Brochure
Planetek Italia Srl - Corporate Profile BrochurePlanetek Italia Srl - Corporate Profile Brochure
Planetek Italia Srl - Corporate Profile Brochure
 
How to become a GDSC Lead GDSC MI AOE.pptx
How to become a GDSC Lead GDSC MI AOE.pptxHow to become a GDSC Lead GDSC MI AOE.pptx
How to become a GDSC Lead GDSC MI AOE.pptx
 
3 Pitfalls Everyone Should Avoid with Cloud Data
3 Pitfalls Everyone Should Avoid with Cloud Data3 Pitfalls Everyone Should Avoid with Cloud Data
3 Pitfalls Everyone Should Avoid with Cloud Data
 
EMEA What is ThousandEyes? Webinar
EMEA What is ThousandEyes? WebinarEMEA What is ThousandEyes? Webinar
EMEA What is ThousandEyes? Webinar
 
My key hands-on projects in Quantum, and QAI
My key hands-on projects in Quantum, and QAIMy key hands-on projects in Quantum, and QAI
My key hands-on projects in Quantum, and QAI
 
Top 10 Squarespace Development Companies
Top 10 Squarespace Development CompaniesTop 10 Squarespace Development Companies
Top 10 Squarespace Development Companies
 
Explore the UiPath Community and ways you can benefit on your journey to auto...
Explore the UiPath Community and ways you can benefit on your journey to auto...Explore the UiPath Community and ways you can benefit on your journey to auto...
Explore the UiPath Community and ways you can benefit on your journey to auto...
 
TrustArc Webinar - How to Live in a Post Third-Party Cookie World
TrustArc Webinar - How to Live in a Post Third-Party Cookie WorldTrustArc Webinar - How to Live in a Post Third-Party Cookie World
TrustArc Webinar - How to Live in a Post Third-Party Cookie World
 
Introduction - IPLOOK NETWORKS CO., LTD.
Introduction - IPLOOK NETWORKS CO., LTD.Introduction - IPLOOK NETWORKS CO., LTD.
Introduction - IPLOOK NETWORKS CO., LTD.
 
2024.03.12 Cost drivers of cultivated meat production.pdf
2024.03.12 Cost drivers of cultivated meat production.pdf2024.03.12 Cost drivers of cultivated meat production.pdf
2024.03.12 Cost drivers of cultivated meat production.pdf
 

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 »
  • 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