SlideShare a Scribd company logo
1 of 33
Download to read offline
BOOST YOUR DEVELOPMENT WITH PROPER API DESIGN
By Marcus Held
ABOUT ME
Senior developer @InnoGames
I develop backends for millions of players worldwide
Started programming in the age of 12
In the gaming industry since 2014
www.code-held.com
@MarHeldro
MOTIVATION
Faster development speed with well-designed
architecture
Isolated modules lead to isolated technical depth
Its more fun to use a well-designed module
Read further in our InnoGames Techblog
tech.innogames.com
TABLE OF CONTENTS
01 Domain Design
02 Value Objects And Entities
03 Model Integrity
04 API Design
EXAMPLE APPLICATION
Available on
github.com/mld-ger
DOMAIN DESIGN
01
DOMAIN DESIGN
"A domain is a field of study that defines a set of common
requirements, terminology, and functionality [...]"
- Wikipedia
DOMAIN DESIGN
WHAT YOU GET
à Restricted visibility
à Grouping
à Understanding of boundaries
à Restricted data access
DOMAIN DESIGN
HOW TO FIND YOUR DOMAIN
Think about data and their relations
DOMAIN DESIGN
HOW TO FIND YOUR DOMAIN
Think about data and their relations
DOMAIN DESIGN
HOW TO FIND YOUR DOMAIN
Think about data and their relations
VALUE OBJECTS AND ENTITIES
02
VALUE OBJECTS AND ENTITIES
ENTITY
Identified by ID
Our apartment is an entity and its ID is the address
public class ResourceEntity {
private final String name;
private MoneyVO price;
[...]
}
private final ResourceIdVO id;
VALUE OBJECTS AND ENTITIES
VALUE OBJECT
Described by its attributes
An apple is described by its color, size and type
Should be immutable
public class MoneyVO {
private BigDecimal value;
[...]
}
MODEL INTEGRITY
03
MODEL INTEGRITY
Every model should exclusively hold, transform or
modify information it holds.
MODEL INTEGRITY
EVERY MODEL SHOULD EXCLUSIVELY HOLD, TRANSFORM OR MODIFY INFORMATION IT HOLDS
public class UserEntity {
private MoneyVO money;
}
private boolean isBankrupt;
MODEL INTEGRITY
EVERY MODEL SHOULD EXCLUSIVELY HOLD, TRANSFORM OR MODIFY INFORMATION IT HOLDS
Different presentation of the same information should derive by a transformation method
public class UserEntity {
private MoneyVO money;
public boolean isBankrupt() {
return money.isNegative();
}
}
MODEL INTEGRITY
EVERY MODEL SHOULD EXCLUSIVELY HOLD, TRANSFORM OR MODIFY INFORMATION IT HOLDS
Class is responsible to ensure validity of its data
public class UserEntity {
private MoneyVO money;
public void subtractMoney(MoneyVO value) throws NotEnoughMoneyException {
MoneyVO subtract = money.subtract(value);
if (subtract.isNegative()) {
throw new NotEnoughMoneyException(money, value);
}
money = subtract;
}
}
→ Changes are only allowed through internal methods
PROVIDE FACTORIES
Enables you to restrict visibility
You can use injected dependencies
public class ResourceFactory {
private final ResourceIdGenerator resourceIdGenerator;
[...]
create(String name, String price) {
return new ResourceEntity(
resourceIdGenerator.newId(),
name,
new MoneyVO(price)
);
}
}
private final ResourceIdGenerator resourceIdGenerator;
resourceIdGenerator.newId(),
ResourceEntity
PACKAGE STRUCTURE
You usually search with three different intentions:
1. You know the name of a class
2. You know the interface or superclass
3. You know the feature it belongs to
→ Search function of your IDE
→ Hierarchy of your IDE
→ Package structure
PACKAGE STRUCTURE
One package per domain
Enables you to restrict visibility
API DESIGN
04
EXPOSE A THIN BUT DESCRIPTIVE API
The API is EVERYTHING that can be seen from the outside
lowest visibility as necessary
Every constant should be public
The exposed API should be as
easy to use as possible
PROVIDE CLASS DOCUMENTATION
What does the class do?
Which data does the class hold or manipulate?
How should the class be used (with examples)?
Is your class thread safe?
/**
* Represents a resource. Every resource has a unique {@link ResourceIdVO}.
* <p>
* Use {@link ResourceFactory#create(String, String)} to generate new instances.
*/
public class ResourceEntity {
Every resource has a unique {@link ResourceIdVO}.
Use {@link ResourceFactory#create(String, String)} to generate new instances.
WRITE DESCRIPTIVE SIGNATURES
Every public method should be understandable without looking into its body
Best solution: The signature describes the functionality
public int buy(String user1, String user2, String resource, int amount)String user1, String user2 String resourceint
WRITE DESCRIPTIVE SIGNATURES
Every public method should be understandable without looking into its body
Best solution: The signature describes the functionality
public int buy(String user1, String user2, String resource, int amount)
public TransactionId buy(UserId buyer, UserId seller, String resourceName, int amount)
String user1, String user2 String resourceint
UserId buyer, UserId seller String resourceNameTransactionId
DESCRIBE THE CONTRACT OF YOUR METHODS
You can't describe everything in the signature
The contract of a method describes the boundaries and side effects
/**
* Creates a new {@link ResourceEntity} with a unique id. This method is thread-safe.
*
* @param name The name of the resource
* @param price The price of the resource. The String must be interpretable by
* {@link BigDecimal#BigDecimal(String)}. A price must be positive.
* @return A new {@link ResourceEntity}
*/
ResourceEntity create(String name, String price);
unique id This method is thread-safe.
The String must be interpretable by
{@link BigDecimal#BigDecimal(String)} A price must be positive.
DESCRIBE THE CONTRACT OF YOUR METHODS
You can't describe everything in the signature
The contract of a method describes the boundaries and side effects
/**
* Creates a new {@link ResourceEntity} with a unique id. This method is thread-safe.
*
* @param name The name of the resource
* @param price The price of the resource. The String must be interpretable by
* {@link BigDecimal#BigDecimal(String)}. A price must be positive.
* @return A new {@link ResourceEntity}
*/
ResourceEntity create(String name, String price);
unique id This method is thread-safe.
The String must be interpretable by
{@link BigDecimal#BigDecimal(String)} A price must be positive.
ResourceEntity create(String name, String price) {
return new ResourceEntity(
resourceIdGenerator.newId(),
name,
new MoneyVO(price)
);
} private class ResourceIdGenerator {
// Use AtomicInteger to make the generator thread safe.
private AtomicInteger counter = new AtomicInteger(0);
ResourceIdVO newId() {
return new ResourceIdVO(counter.incrementAndGet());
}
}
DESCRIBE THE CONTRACT OF YOUR METHODS
ResourceEntity createWithUniqueIdThreadSafe(
String name,
String positiveBigDecimalInterpretablePrice
);
NO.
DESCRIBE THE CONTRACT OF YOUR METHODS
MAKE YOUR DEEPEST LAYER THE PRETTIEST
The deeper
the more…
… effort
… expensive
… used
CONCLUSION
Make it as easy as possible for the caller to use
your module
The code must be easy to read, not to write
"The ratio of time spent reading versus writing is
well over 10 to 1."
- Robert C. Martin (Clean Code, 2009)
IT ALL COMES TO AN END…
www.code-held.com
@MarHeldro

More Related Content

What's hot (6)

Intro to Programming for Communicators - Hacks/Hackers ATX
Intro to Programming for Communicators - Hacks/Hackers ATXIntro to Programming for Communicators - Hacks/Hackers ATX
Intro to Programming for Communicators - Hacks/Hackers ATX
 
Handlebars
HandlebarsHandlebars
Handlebars
 
201005 accelerometer and core Location
201005 accelerometer and core Location201005 accelerometer and core Location
201005 accelerometer and core Location
 
psnreddy php-oops
psnreddy  php-oopspsnreddy  php-oops
psnreddy php-oops
 
Policy Injection in ASP.NET using Enterprise Library 3.0
Policy Injection in ASP.NET using Enterprise Library 3.0Policy Injection in ASP.NET using Enterprise Library 3.0
Policy Injection in ASP.NET using Enterprise Library 3.0
 
Spring Data JPA from 0-100 in 60 minutes
Spring Data JPA from 0-100 in 60 minutesSpring Data JPA from 0-100 in 60 minutes
Spring Data JPA from 0-100 in 60 minutes
 

Similar to Boost Your Development With Proper API Design

Similar to Boost Your Development With Proper API Design (20)

CDI @javaonehyderabad
CDI @javaonehyderabadCDI @javaonehyderabad
CDI @javaonehyderabad
 
Dart for Java Developers
Dart for Java DevelopersDart for Java Developers
Dart for Java Developers
 
Multilingualism makes better programmers
Multilingualism makes better programmersMultilingualism makes better programmers
Multilingualism makes better programmers
 
Hibernate II
Hibernate IIHibernate II
Hibernate II
 
Object Oriented Programming Basics with PHP
Object Oriented Programming Basics with PHPObject Oriented Programming Basics with PHP
Object Oriented Programming Basics with PHP
 
A resource oriented framework using the DI/AOP/REST triangle
A resource oriented framework using the DI/AOP/REST triangleA resource oriented framework using the DI/AOP/REST triangle
A resource oriented framework using the DI/AOP/REST triangle
 
Introduction to Spring Boot.pdf
Introduction to Spring Boot.pdfIntroduction to Spring Boot.pdf
Introduction to Spring Boot.pdf
 
Android architecture
Android architecture Android architecture
Android architecture
 
Clean code
Clean codeClean code
Clean code
 
Extending Java EE with CDI and JBoss Forge
Extending Java EE with CDI and JBoss ForgeExtending Java EE with CDI and JBoss Forge
Extending Java EE with CDI and JBoss Forge
 
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)
 
Spark IT 2011 - Context & Dependency Injection in the Java EE 6 Ecosystem
Spark IT 2011 - Context & Dependency Injection in the Java EE 6 EcosystemSpark IT 2011 - Context & Dependency Injection in the Java EE 6 Ecosystem
Spark IT 2011 - Context & Dependency Injection in the Java EE 6 Ecosystem
 
08ui.pptx
08ui.pptx08ui.pptx
08ui.pptx
 
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)
 
Let's write secure Drupal code! - DrupalCamp London 2019
Let's write secure Drupal code! - DrupalCamp London 2019Let's write secure Drupal code! - DrupalCamp London 2019
Let's write secure Drupal code! - DrupalCamp London 2019
 
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
 
Relevance trilogy may dream be with you! (dec17)
Relevance trilogy  may dream be with you! (dec17)Relevance trilogy  may dream be with you! (dec17)
Relevance trilogy may dream be with you! (dec17)
 
CDI in JEE6
CDI in JEE6CDI in JEE6
CDI in JEE6
 
Services Drupalcamp Stockholm 2009
Services Drupalcamp Stockholm 2009Services Drupalcamp Stockholm 2009
Services Drupalcamp Stockholm 2009
 
Typed data in drupal 8
Typed data in drupal 8Typed data in drupal 8
Typed data in drupal 8
 

Recently uploaded

Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
VictoriaMetrics
 

Recently uploaded (20)

WSO2Con2024 - Simplified Integration: Unveiling the Latest Features in WSO2 L...
WSO2Con2024 - Simplified Integration: Unveiling the Latest Features in WSO2 L...WSO2Con2024 - Simplified Integration: Unveiling the Latest Features in WSO2 L...
WSO2Con2024 - Simplified Integration: Unveiling the Latest Features in WSO2 L...
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
 
WSO2Con2024 - Software Delivery in Hybrid Environments
WSO2Con2024 - Software Delivery in Hybrid EnvironmentsWSO2Con2024 - Software Delivery in Hybrid Environments
WSO2Con2024 - Software Delivery in Hybrid Environments
 
WSO2Con2024 - Navigating the Digital Landscape: Transforming Healthcare with ...
WSO2Con2024 - Navigating the Digital Landscape: Transforming Healthcare with ...WSO2Con2024 - Navigating the Digital Landscape: Transforming Healthcare with ...
WSO2Con2024 - Navigating the Digital Landscape: Transforming Healthcare with ...
 
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
 
WSO2CON 2024 - OSU & WSO2: A Decade Journey in Integration & Innovation
WSO2CON 2024 - OSU & WSO2: A Decade Journey in Integration & InnovationWSO2CON 2024 - OSU & WSO2: A Decade Journey in Integration & Innovation
WSO2CON 2024 - OSU & WSO2: A Decade Journey in Integration & Innovation
 
WSO2Con2024 - Unleashing the Financial Potential of 13 Million People
WSO2Con2024 - Unleashing the Financial Potential of 13 Million PeopleWSO2Con2024 - Unleashing the Financial Potential of 13 Million People
WSO2Con2024 - Unleashing the Financial Potential of 13 Million People
 
WSO2CON 2024 - Architecting AI in the Enterprise: APIs and Applications
WSO2CON 2024 - Architecting AI in the Enterprise: APIs and ApplicationsWSO2CON 2024 - Architecting AI in the Enterprise: APIs and Applications
WSO2CON 2024 - Architecting AI in the Enterprise: APIs and Applications
 
WSO2CON 2024 Slides - Unlocking Value with AI
WSO2CON 2024 Slides - Unlocking Value with AIWSO2CON 2024 Slides - Unlocking Value with AI
WSO2CON 2024 Slides - Unlocking Value with AI
 
WSO2CON 2024 Slides - Open Source to SaaS
WSO2CON 2024 Slides - Open Source to SaaSWSO2CON 2024 Slides - Open Source to SaaS
WSO2CON 2024 Slides - Open Source to SaaS
 
WSO2CON 2024 - Lessons from the Field: Legacy Platforms – It's Time to Let Go...
WSO2CON 2024 - Lessons from the Field: Legacy Platforms – It's Time to Let Go...WSO2CON 2024 - Lessons from the Field: Legacy Platforms – It's Time to Let Go...
WSO2CON 2024 - Lessons from the Field: Legacy Platforms – It's Time to Let Go...
 
WSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go PlatformlessWSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go Platformless
 
WSO2Con2024 - Organization Management: The Revolution in B2B CIAM
WSO2Con2024 - Organization Management: The Revolution in B2B CIAMWSO2Con2024 - Organization Management: The Revolution in B2B CIAM
WSO2Con2024 - Organization Management: The Revolution in B2B CIAM
 
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
 
WSO2CON 2024 - Not Just Microservices: Rightsize Your Services!
WSO2CON 2024 - Not Just Microservices: Rightsize Your Services!WSO2CON 2024 - Not Just Microservices: Rightsize Your Services!
WSO2CON 2024 - Not Just Microservices: Rightsize Your Services!
 
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
 
WSO2Con2024 - Hello Choreo Presentation - Kanchana
WSO2Con2024 - Hello Choreo Presentation - KanchanaWSO2Con2024 - Hello Choreo Presentation - Kanchana
WSO2Con2024 - Hello Choreo Presentation - Kanchana
 
WSO2CON 2024 - Building a Digital Government in Uganda
WSO2CON 2024 - Building a Digital Government in UgandaWSO2CON 2024 - Building a Digital Government in Uganda
WSO2CON 2024 - Building a Digital Government in Uganda
 
WSO2Con204 - Hard Rock Presentation - Keynote
WSO2Con204 - Hard Rock Presentation - KeynoteWSO2Con204 - Hard Rock Presentation - Keynote
WSO2Con204 - Hard Rock Presentation - Keynote
 
WSO2Con2024 - GitOps in Action: Navigating Application Deployment in the Plat...
WSO2Con2024 - GitOps in Action: Navigating Application Deployment in the Plat...WSO2Con2024 - GitOps in Action: Navigating Application Deployment in the Plat...
WSO2Con2024 - GitOps in Action: Navigating Application Deployment in the Plat...
 

Boost Your Development With Proper API Design

  • 1. BOOST YOUR DEVELOPMENT WITH PROPER API DESIGN By Marcus Held
  • 2. ABOUT ME Senior developer @InnoGames I develop backends for millions of players worldwide Started programming in the age of 12 In the gaming industry since 2014 www.code-held.com @MarHeldro
  • 3. MOTIVATION Faster development speed with well-designed architecture Isolated modules lead to isolated technical depth Its more fun to use a well-designed module Read further in our InnoGames Techblog tech.innogames.com
  • 4. TABLE OF CONTENTS 01 Domain Design 02 Value Objects And Entities 03 Model Integrity 04 API Design
  • 7. DOMAIN DESIGN "A domain is a field of study that defines a set of common requirements, terminology, and functionality [...]" - Wikipedia
  • 8. DOMAIN DESIGN WHAT YOU GET à Restricted visibility à Grouping à Understanding of boundaries à Restricted data access
  • 9. DOMAIN DESIGN HOW TO FIND YOUR DOMAIN Think about data and their relations
  • 10. DOMAIN DESIGN HOW TO FIND YOUR DOMAIN Think about data and their relations DOMAIN DESIGN HOW TO FIND YOUR DOMAIN Think about data and their relations
  • 11. VALUE OBJECTS AND ENTITIES 02
  • 12. VALUE OBJECTS AND ENTITIES ENTITY Identified by ID Our apartment is an entity and its ID is the address public class ResourceEntity { private final String name; private MoneyVO price; [...] } private final ResourceIdVO id;
  • 13. VALUE OBJECTS AND ENTITIES VALUE OBJECT Described by its attributes An apple is described by its color, size and type Should be immutable public class MoneyVO { private BigDecimal value; [...] }
  • 15. MODEL INTEGRITY Every model should exclusively hold, transform or modify information it holds.
  • 16. MODEL INTEGRITY EVERY MODEL SHOULD EXCLUSIVELY HOLD, TRANSFORM OR MODIFY INFORMATION IT HOLDS public class UserEntity { private MoneyVO money; } private boolean isBankrupt;
  • 17. MODEL INTEGRITY EVERY MODEL SHOULD EXCLUSIVELY HOLD, TRANSFORM OR MODIFY INFORMATION IT HOLDS Different presentation of the same information should derive by a transformation method public class UserEntity { private MoneyVO money; public boolean isBankrupt() { return money.isNegative(); } }
  • 18. MODEL INTEGRITY EVERY MODEL SHOULD EXCLUSIVELY HOLD, TRANSFORM OR MODIFY INFORMATION IT HOLDS Class is responsible to ensure validity of its data public class UserEntity { private MoneyVO money; public void subtractMoney(MoneyVO value) throws NotEnoughMoneyException { MoneyVO subtract = money.subtract(value); if (subtract.isNegative()) { throw new NotEnoughMoneyException(money, value); } money = subtract; } } → Changes are only allowed through internal methods
  • 19. PROVIDE FACTORIES Enables you to restrict visibility You can use injected dependencies public class ResourceFactory { private final ResourceIdGenerator resourceIdGenerator; [...] create(String name, String price) { return new ResourceEntity( resourceIdGenerator.newId(), name, new MoneyVO(price) ); } } private final ResourceIdGenerator resourceIdGenerator; resourceIdGenerator.newId(), ResourceEntity
  • 20. PACKAGE STRUCTURE You usually search with three different intentions: 1. You know the name of a class 2. You know the interface or superclass 3. You know the feature it belongs to → Search function of your IDE → Hierarchy of your IDE → Package structure
  • 21. PACKAGE STRUCTURE One package per domain Enables you to restrict visibility
  • 23. EXPOSE A THIN BUT DESCRIPTIVE API The API is EVERYTHING that can be seen from the outside lowest visibility as necessary Every constant should be public The exposed API should be as easy to use as possible
  • 24. PROVIDE CLASS DOCUMENTATION What does the class do? Which data does the class hold or manipulate? How should the class be used (with examples)? Is your class thread safe? /** * Represents a resource. Every resource has a unique {@link ResourceIdVO}. * <p> * Use {@link ResourceFactory#create(String, String)} to generate new instances. */ public class ResourceEntity { Every resource has a unique {@link ResourceIdVO}. Use {@link ResourceFactory#create(String, String)} to generate new instances.
  • 25. WRITE DESCRIPTIVE SIGNATURES Every public method should be understandable without looking into its body Best solution: The signature describes the functionality public int buy(String user1, String user2, String resource, int amount)String user1, String user2 String resourceint
  • 26. WRITE DESCRIPTIVE SIGNATURES Every public method should be understandable without looking into its body Best solution: The signature describes the functionality public int buy(String user1, String user2, String resource, int amount) public TransactionId buy(UserId buyer, UserId seller, String resourceName, int amount) String user1, String user2 String resourceint UserId buyer, UserId seller String resourceNameTransactionId
  • 27. DESCRIBE THE CONTRACT OF YOUR METHODS You can't describe everything in the signature The contract of a method describes the boundaries and side effects /** * Creates a new {@link ResourceEntity} with a unique id. This method is thread-safe. * * @param name The name of the resource * @param price The price of the resource. The String must be interpretable by * {@link BigDecimal#BigDecimal(String)}. A price must be positive. * @return A new {@link ResourceEntity} */ ResourceEntity create(String name, String price); unique id This method is thread-safe. The String must be interpretable by {@link BigDecimal#BigDecimal(String)} A price must be positive.
  • 28. DESCRIBE THE CONTRACT OF YOUR METHODS You can't describe everything in the signature The contract of a method describes the boundaries and side effects /** * Creates a new {@link ResourceEntity} with a unique id. This method is thread-safe. * * @param name The name of the resource * @param price The price of the resource. The String must be interpretable by * {@link BigDecimal#BigDecimal(String)}. A price must be positive. * @return A new {@link ResourceEntity} */ ResourceEntity create(String name, String price); unique id This method is thread-safe. The String must be interpretable by {@link BigDecimal#BigDecimal(String)} A price must be positive. ResourceEntity create(String name, String price) { return new ResourceEntity( resourceIdGenerator.newId(), name, new MoneyVO(price) ); } private class ResourceIdGenerator { // Use AtomicInteger to make the generator thread safe. private AtomicInteger counter = new AtomicInteger(0); ResourceIdVO newId() { return new ResourceIdVO(counter.incrementAndGet()); } }
  • 29. DESCRIBE THE CONTRACT OF YOUR METHODS ResourceEntity createWithUniqueIdThreadSafe( String name, String positiveBigDecimalInterpretablePrice ); NO.
  • 30. DESCRIBE THE CONTRACT OF YOUR METHODS
  • 31. MAKE YOUR DEEPEST LAYER THE PRETTIEST The deeper the more… … effort … expensive … used
  • 32. CONCLUSION Make it as easy as possible for the caller to use your module The code must be easy to read, not to write "The ratio of time spent reading versus writing is well over 10 to 1." - Robert C. Martin (Clean Code, 2009)
  • 33. IT ALL COMES TO AN END… www.code-held.com @MarHeldro