Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Journey with Marvin: Path to Clean Architecture

Journey with Marvin: Path to Clean Architecture

A research on Java Spring validations led to an unexpected journey towards refactoring an application to adhere (somewhat) to Uncle Bob's Clean Architecture (https://blog.8thlight.com/uncle-bob/2012/08/13/the-clean-architecture.html)

Alan Yeo

May 27, 2016
Tweet

Other Decks in Programming

Transcript

  1. What is Marvin? Chat bot interface that enables different chat

    clients to interact with the same backend application
  2. public class CustomerValidator implements Validator {
 
 private final Validator

    addressValidator;
 
 public CustomerValidator(Validator addressValidator) {
 if (addressValidator == null) {
 throw new IllegalArgumentException("The supplied [Validator] is " +
 "required and must not be null.");
 }
 if (!addressValidator.supports(Address.class)) {
 throw new IllegalArgumentException("The supplied [Validator] must " +
 "support the validation of [Address] instances.");
 }
 this.addressValidator = addressValidator;
 }
 
 public boolean supports(Class clazz) {
 return Customer.class.isAssignableFrom(clazz);
 }
 
 public void validate(Object target, Errors errors) {
 ValidationUtils.rejectIfEmptyOrWhitespace(errors, "firstName", "field.required");
 ValidationUtils.rejectIfEmptyOrWhitespace(errors, "surname", "field.required");
 Customer customer = (Customer) target;
 try {
 errors.pushNestedPath("address");
 ValidationUtils.invokeValidator(this.addressValidator, customer.getAddress(), errors);
 } finally {
 errors.popNestedPath();
 }
 }
 } http://docs.spring.io/spring/docs/current/spring-framework-reference/html/validation.html#validator
  3. Annotation-style validations • Gives a clear correlation between fields and

    validations • Forces a declarative style of performing validations • Eliminates possibility of typo when specifying field to validate
  4. Structural vs Domain validations Structural: "name" string is not blank,

    "date" string matches a regex pattern, etc Domain: presence of Command object with some "name", uniqueness, etc
  5. Let's do a simple exercise to identify these two types!

    SlackController in `master` branch
  6. Learnings #5: Use Builder pattern to construct DTOs, especially when

    you have many arguments in the constructor Inspired by Item 2 of Joshua Bloch's Effective Java Second Edition book
  7. Learnings #6: Avoid throwing exceptions if possible and use a

    result object to encapsulate information
  8. Learnings #7: Handle exceptions at the right level of abstraction

    Inspired by Item 61 of Joshua Bloch's Effective Java Second Edition book
  9. What lies ahead? • Integration with CQRS and Event Sourcing

    • Integration with other chat clients (e.g. Telegram)