SlideShare uma empresa Scribd logo
1 de 48
Baixar para ler offline
20 – 22 June 2007
Metropolis Antwerp, Belgium
Improving Applications Design with a
Rich Domain Model
Chris Richardson
Author of POJOs in Action
www.chrisrichardson.net
About Chris
              Grew up in England
              Live in Oakland, CA
              Twenty years of software
              development experience
              –   Building object-oriented software
                  since 1986
              –   Using Java since 1996
              –   Using J2EE since 1999
              Author of POJOs in Action
              Speaker at JavaOne, JavaPolis,
              NFJS, JUGs, ….
              Chair of the eBIG Java SIG in
              Oakland (www ebig org)
                        (www.ebig.org)
              Run a consulting and training
              company that helps organizations
              build better software faster
Overall presentation goal


 Learn how to improve application design
  with truly object-oriented business logic
Agenda
 The
 Th ups and d
            d downs of OO design
                       f   d i
 Overview of the Domain Model pattern
 Domain model building blocks
 Common code smells
 Refactoring existing code
Designing business logic
 Spring promotes good design practices:
  – Dependency injection for loose coupling
  – AOP for handling cross cutting concerns
 But you must decide how to structure your
 business logic:
  – Domain Model pattern – object-oriented
  – Transaction Script pattern – procedural
 Choice of pattern impacts ease of:
  – Development testing maintainability ….
    Development, testing, maintainability,
Lots of procedural Java code
           Java is an object oriented language
                      object-oriented

                           AND

Object-oriented design is a better way to tackle complexity

                           YET

Many complex enterprise Java applications are written in a
                     procedural style
Example banking application
Example procedural design
Example procedural code
public class MoneyTransferServiceProceduralImpl implements MoneyTransferService {   public class Account {

p
public BankingTransaction transfer(String fromAccountId, String toAccountId,
             g                    (     g               ,     g            ,        p
                                                                                    public static final int NEVER = 1;
                                                                                                                     ;
    double amount) throws MoneyTransferException {                                  public static final int ALLOWED = 2;
  Account fromAccount = accountDAO.findAccount(fromAccountId);
  Account toAccount = accountDAO.findAccount(toAccountId);                          private   int id;
  assert amount > 0;                                                                private   double balance;
  double newBalance = fromAccount.getBalance() - amount;                            private   int overdraftPolicy;
  switch (fromAccount.getOverdraftPolicy()) {                                       private   String accountId;
  case Account.NEVER:                                                               private   Date dateOpened;
    if (newBalance < 0)                                                             private   double requiredYearsOpen;
      throw new MoneyTransferException("In sufficient funds");                      private   double limit;
    break;
  case Account.ALLOWED:                                                             Account() {}
    Calendar then = Calendar.getInstance();
    then.setTime(fromAccount.getDateOpened());
    Calendar now = Calendar.getInstance();                                          public Account(String accountId, double balance, int
                                                                                    overdraftPolicy,
      double yearsOpened = now.get(Calendar.YEAR) - then.get(Calendar.YEAR);                         Date dateOpened, double requiredYearsOpen,
      int monthsOpened = now.get(Calendar.MONTH) - then.get(Calendar.MONTH);        double limit)
      if (monthsOpened < 0) {                                                        {….. }
        yearsOpened--;
              O     d
        monthsOpened += 12;                                                         public int getId() {return id;}
      }
      yearsOpened = yearsOpened + (monthsOpened / 12.0);                            public String getAccountId() {return accountId;}
      if (yearsOpened < fromAccount.getRequiredYearsOpen()
          || newBalance < fromAccount.getLimit())                                   public void setBalance(double balance) { this.balance = balance; }
        throw new MoneyTransferException("Limit exceeded");
      break;                                                                        public double getBalance() { return balance; }
     default:
      throw new MoneyTransferException( Unknown overdraft type: "
                 MoneyTransferException("Unknown                                    public int getOverdraftPolicy() { return overdraftPolicy; }
          + fromAccount.getOverdraftPolicy());
                                                                                    public Date getDateOpened() {     return dateOpened; }
     }
     fromAccount.setBalance(newBalance);                                            public double getRequiredYearsOpen() {
     toAccount.setBalance(toAccount.getBalance() + amount);                             return requiredYearsOpen; }
     TransferTransaction txn = new TransferTransaction(fromAccount, toAccount,
        amount, new Date());                                                        public double getLimit() {return limit; }
     bankingTransactionDAO.addTransaction(txn);                                     }
     return txn;
 }
A seductive programming style
 Implementing new f
 I l     ti       functionality i easy
                      ti   lit is
  – Add a new transaction script
  – Add code to a new transaction script
 No need to do any real design, e.g.
  – Create new classes
  – Determine responsibilities
                 p
Unable to handle complexity
 Works well for simple business logic
  – E.g. the example wasn’t that bad
 But with complex business logic:
  – Large transaction scripts: 100s/1000s LOC
  – Difficult/impossible to understand, test, and maintain
 What’s worse: business logic has a habit of
 growing
  – New requirements ⇒ Add a few more lines to the
    transaction script
  – Many new requirements ⇒ big mess
Today – OO is growing in popularity
 POJOs
  – Plain Old Java Objects
  – Leverage OO features of Java
 O/R mapping frameworks for
 persisting POJO
     i ti POJOs:
  – Hibernate
  – Java Persistence API
  – …
 Spring AOP and AspectJ for
 handling cross-cutting
 concerns:
  –   Transaction management
  –   Security
  –   Logging
  –   Auditing
  –   …
Agenda
 The
 Th ups and d
            d downs of OO design
                       f   d i
 Overview of the Domain Model pattern
 Domain model building blocks
 Common code smells
 Refactoring existing code
Using the Domain Model Pattern
 Business l i spread amongst a collection of
 B i      logic      d         t    ll ti   f
 classes
 Many classes correspond to real world concepts:
 Order, Customer, …
 Many classes are true objects having both:
  – State – fields
  – Behavior – methods that act on the state
Procedural versus OO
An example domain model
DEMO
Code Walkthrough
Benefits of the Domain Model Pattern
 Improved maintainability
  – The design reflects reality
  – The design is more modular
 Improved testability
  – Small classes that can be tested in isolation
 Improved reusability
  – Classes can be used in other applications
 Building a domain model
        g
  – Creates shared understanding
  – Develops an ubiquitous language
Quantifiably simpler methods
 Procedural – few, longer, more   Object-oriented – more,
 complex methods                  simpler,
                                  simpler shorter methods
Drawbacks of the Domain Model pattern

 Requires object-oriented d i skills
 R    i    bj t i t d design kill
 Requires domain model to be
 transparently “mappable” to the data
  – E.g. nice database schema
  – Ugly schemas and data stored in other
    applications is a challenge
When to use it
 The b i
 Th business l i i reasonably complex
                logic is           bl l
 or you anticipate that it will be
 You have the skills to design one
 You can use an ORM framework
Agenda
 The
 Th ups and d
            d downs of OO design
                       f   d i
 Overview of the Domain Model pattern
 Domain model building blocks
 Common code smells
 Refactoring existing code
Domain model building blocks
 Roles k
 R l aka
 stereotypes
 Benefits of roles:
  – Guide design
  – Help name objects
  – Aid understanding
 Roles (from Domain-
             Domain
 Driven Design)
Entity
                          public class Account {
 Objects ith di ti t
 Obj t with a distinct     private int id;

 identity                  private double balance;

                           private OverdraftPolicy overdraftPolicy;

 Typically correspond      private String accountId;

                           private CalendarDate dateOpened;
 to real world concepts    Account() {
                           }

 Almost always             public void debit(double amount) throws MoneyTransferException {
                             assert amount > 0;
                             double originalBalance = balance;
 persistent                  double newBalance = balance - amount;
                             overdraftPolicy.beforeDebitCheck(this, originalBalance, newBalance);
                             balance = newBalance;
                             overdraftPolicy.afterDebitAction(this, originalBalance, newBalance);
                           }

                           public void credit(double amount) {
                             assert amount > 0;
                             balance += amount;
                           }
Value Objects
 Objects that are        public class CalendarDate {

                             private Date date;

 defined by the values       CalendarDate() {
                             }
 of their attributes         public CalendarDate(Date date) {
                               this.date = date;

 Two instances with          }

                             public Date getDate() {

 identical values can        }
                               return date;



 be
 b used  d                   public double getYearsOpen() {
                              Calendar then = Calendar.getInstance();
                              then.setTime(date);
 interchangeably              Calendar now = Calendar.getInstance();

                                 int yearsOpened = now.get(Calendar.YEAR) –

 Often immutable and                               then.get(Calendar.YEAR);
                                 int monthsOpened = now.get(Calendar.MONTH) -
                                                  then.get(Calendar.MONTH);
 persistent                      if (monthsOpened < 0) {
                                   yearsOpened--;
                                   monthsOpened += 12;
                                 }
 Part of an entityy              return yearsOpened + (monthsOpened/12.0);

                             }

                         }
Aggregates
 A cluster of related
 entities and values
 Behaves as a unit
 Has a root
 Has a bou da y
   as boundary
 Objects outside the
 aggregate can only
 reference the root
   f
 Deleting the root
 removes everything
Repositories
                                   public interface AccountRepository {
 Manages a collection of                Account findAccount(String accountId);
 objects                                void addAccount(Account account);

 Provides methods for:             }

 Adding an object
                                   public class HibernateAccountRepository implements AccountRepository {
 Finding object or objects
                                       private HibernateTemplate hibernateTemplate;
 Deleting objects                      public HibernateAccountRepository(HibernateTemplate template) {
                                         hibernateTemplate = template;
                                                      p         p
 Consists of an interface and an       }

 implementation class                  public void addAccount(Account account) {
                                         hibernateTemplate.save(account);
 Encapsulates database access          }

 mechanism                             public Account findAccount(final String accountId) {
                                         return (Account) DataAccessUtils.uniqueResult(hibernateTemplate
                                            .findByNamedQueryAndNamedParam(
 Keeps the ORM framework out                    "Account.findAccountByAccountId", "accountId",
                                                accountId));
 of the domain model                   }

 Similar to a DAO                  }
Services
                                   public interface MoneyTransferService {
 Implements logic that cannot           BankingTransaction transfer(String fromAccountId,
 be put in a single entity                   String toAccountId, double amount)
                                             throws MoneyTransferException;

 Not persistent                    }

 Consists of an interface and an
 implementation class              public class MoneyTransferServiceImpl implements MoneyTransferService
                                   {

 Service method usually:               private final AccountRepository accountRepository;

 Invoked (indirectly) by               p
                                       private final BankingTransactionRepository
                                                           g             p
                                                  bankingTransactionRepository;
                                                                                y

 presentation tier                     public MoneyTransferServiceImpl(AccountRepository accountRepository,
                                          BankingTransactionRepository bankingTransactionRepository) {
 Invokes one or more                     this.accountRepository = accountRepository;
                                         this.bankingTransactionRepository = bankingTransactionRepository;
 repositories                          }

 Invokes one or more entities          public BankingTransaction transfer(String fromAccountId,
                                          String toAccountId, double amount) {
                                         …
 Keep them thin                        }

                                   }
Factories
 Use when a constructor is insufficient
  – Encapsulates complex object creation logic
  – Varying products
 Different kinds of factories
  –F t
    Factory classes
             l
  – Factory methods
 Example: O d F t
 E    l OrderFactory
  – Creates Order from a shopping cart
  – Add li it
    Adds line items
Role of Spring 1
 Use the
 U th POJO programming model
                   i     d l
  – Minimize dependencies on infrastructure frameworks:
    your domain model might outlive them
  – Avoid @DoThisAnnotations: e.g. @Transactional
 Spring instantiates and wires together
  – Services, factories and repositories
 Dependency injection into entities
   p      y j
  – One option is @Configurable but it’s not POJO
  – Hibernate Interceptor/Manual injection is preferable
Role of Spring 2
 Spring
 S i AOP for service-level crosscutting
           f     i l     l        tti
 concerns:
  – E g transaction management, security logging etc
    E.g.            management security,         etc.
 AspectJ for entity and value object crosscutting
 concerns
  – E.g. tracking changes to fields
  – AJC/Load-time weaving has a cost
                          g
 Use Spring ORM in the repository
 implementation classes
Agenda
 The
 Th ups and d
            d downs of OO design
                       f   d i
 Overview of the Domain Model pattern
 Domain model building blocks
 Common code smells
 Refactoring existing code
Overview of code smells
 Code
 C d smell = something about th code
           ll      thi    b t the d
 that does not seem right
 Impacts ease of development and testing
 Some are non-OOD
 Some are the consequences of non-OOD
Long method
 Methods should be short      p
                              public class MoneyTransferServiceProceduralImpl implements MoneyTransferService {
                                               y                           p    p            y

                              public BankingTransaction transfer(String fromAccountId, String toAccountId,
                                  double amount) throws MoneyTransferException {
                                Account fromAccount = accountDAO.findAccount(fromAccountId);

 But business logic is          Account toAccount = accountDAO.findAccount(toAccountId);
                                assert amount > 0;
                                double newBalance = fromAccount.getBalance() - amount;

 concentrated in the            switch (fromAccount.getOverdraftPolicy()) {
                                case Account.NEVER:
                                  if (newBalance < 0)


 services ⇒ l
                                    throw new MoneyTransferException( In sufficient funds");
                                              MoneyTransferException("In            funds );

     i      long methods
                     th d         break;
                                case Account.ALLOWED:
                                  Calendar then = Calendar.getInstance();
                                  then.setTime(fromAccount.getDateOpened());

 Long methods are difficult       Calendar now = Calendar.getInstance();

                                    double yearsOpened = now.get(Calendar.YEAR) - then.get(Calendar.YEAR);
                                    int monthsOpened = now.get(Calendar.MONTH) - then.get(Calendar.MONTH);

 to:                                if (monthsOpened < 0) {
                                      yearsOpened--;
                                      monthsOpened += 12
                                           th O    d + 12;
                                    }

 – Read and understand              yearsOpened = yearsOpened + (monthsOpened / 12.0);
                                    if (yearsOpened < fromAccount.getRequiredYearsOpen()
                                        || newBalance < fromAccount.getLimit())
                                      throw new MoneyTransferException("Limit exceeded");
 – Maintain                         break;
                                   default:
                                    throw new MoneyTransferException("Unknown overdraft type: "

 – Test                            }
                                        + fromAccount.getOverdraftPolicy());


                                   fromAccount.setBalance(newBalance);

 Fix:                              toAccount.setBalance(toAccount.getBalance() + amount);
                                   TransferTransaction txn = new TransferTransaction(fromAccount, toAccount,
                                      amount, new Date());
                                   bankingTransactionDAO.addTransaction(txn);
                                   return txn;
 – Splitting into smaller      }


   methods
Feature Envy
 Methods that are far     p
                          public class MoneyTransferServiceProceduralImpl implements MoneyTransferService {
                                           y                           p    p            y

                          public BankingTransaction transfer(String fromAccountId, String toAccountId, double amount) throws
                          MoneyTransferException {
                            Account fromAccount = accountDAO.findAccount(fromAccountId);

 too interested in data     Account toAccount = accountDAO.findAccount(toAccountId);
                            assert amount > 0;
                            double newBalance = fromAccount.getBalance() - amount;
                            switch (fromAccount.getOverdraftPolicy()) {

 belonging to other
       g g                  case Account.NEVER:
                              if (newBalance < 0)
                                throw new MoneyTransferException( In sufficient funds");
                              break;
                                          MoneyTransferException("In            funds );



 classes                    case Account.ALLOWED:
                              Calendar then = Calendar.getInstance();
                              then.setTime(fromAccount.getDateOpened());
                              Calendar now = Calendar.getInstance();



 Results in:                    double yearsOpened = now.get(Calendar.YEAR) - then.get(Calendar.YEAR);
                                int monthsOpened = now.get(Calendar.MONTH) - then.get(Calendar.MONTH);
                                if (monthsOpened < 0) {
                                  yearsOpened--;
                                  monthsOpened += 12
                                       th O    d + 12;

 – Poor encapsulation           }
                                yearsOpened = yearsOpened + (monthsOpened / 12.0);
                                if (yearsOpened < fromAccount.getRequiredYearsOpen()
                                    || newBalance < fromAccount.getLimit())


 – Long methods                   throw new MoneyTransferException("Limit exceeded");
                                break;
                               default:
                                throw new MoneyTransferException("Unknown overdraft type: "
                                    + fromAccount.getOverdraftPolicy());


 Fix by moving                 }
                               fromAccount.setBalance(newBalance);
                               toAccount.setBalance(toAccount.getBalance() + amount);


 methods to the class          TransferTransaction txn = new TransferTransaction(fromAccount, toAccount,
                                  amount, new Date());
                               bankingTransactionDAO.addTransaction(txn);
                               return txn;


 that has the data
                           }
Data class
                            public class Account {
 Classes that are j t
 Cl         th t     just   public static final int NEVER = 1;
                            public static final int ALLOWED = 2;

 getters and setters        private
                            private
                                      int id;
                                      double balance;
                            private   int overdraftPolicy;

 No business logic -        private
                            private
                            private
                                      String accountId;
                                      Date dateOpened;
                                      double requiredYearsOpen;
                            private   double limit;

 it’s in the service        Account() {}



 Leads to:                  public Account(String accountId, double balance, int overdraftPolicy,

                             {….. }
                                            Date dateOpened, double requiredYearsOpen, double limit)



  – Feature envy            public int getId() {return id;}

                            public String getAccountId() {return accountId;}


 Fix by moving              public void setBalance(double balance) { this.balance = balance; }

                            public double getBalance() { return balance; }

 methods that act on        public int getOverdraftPolicy() { return overdraftPolicy; }

                            public Date getDateOpened() {     return dateOpened; }

 data into class            public double getRequiredYearsOpen() {       return requiredYearsOpen; }

                            public double getLimit() {return limit; }
                            }
Primitive Obsession
                        public class Account {
                          private Date dateOpened;
 Code uses built in
             built-in   }

 types instead of       public class Account {
                          private Date dateOpened;
 application classes    }

                        public class MoneyTransferServiceProceduralImpl implements
 Consequences:
 C                      MoneyTransferService {

                        public BankingTransaction transfer(String fromAccountId, String
  – Reduces             toAccountId,
                            double amount) throws MoneyTransferException {
    understandability      Account fromAccount = accountDAO.findAccount(fromAccountId);
                           Account toAccount = accountDAO findAccount(toAccountId);
                                                accountDAO.findAccount(toAccountId);
  – L
    Long methods
            h d            …
                            Calendar then = Calendar.getInstance();
  – Code duplication        then.setTime(fromAccount.getDateOpened());
                            Calendar now = Calendar.getInstance();

  – Added complexity        double yearsOpened = now.get(Calendar.YEAR) -
                                                        then.get(Calendar.YEAR);
                            int monthsOpened = now.get(Calendar.MONTH) –
 Fix by moving data                                   then.get(Calendar.MONTH);
                            if (monthsOpened < 0) {
 and code into new            yearsOpened--;
                              monthsOpened += 12;
 class                      }
                            yea sOpe ed
                            yearsOpened = yea sOpe ed + (monthsOpened / 12.0);
                                              yearsOpened     ( o t sOpe ed      0);
                            if (yearsOpened < fromAccount.getRequiredYearsOpen()
                                || newBalance < fromAccount.getLimit())
                        …
                        }
Switch Statements
                                 public class Account {
 Use of type codes and           public static final int NEVER = 1;
 switch statements instead       public static final int ALLOWED = 2;
                                 …
 of polymorphism
 Consequences:
 C                               public class MoneyTransferServiceProceduralImpl
                                 implements MoneyTransferService {
 – Longer methods
                                 public BankingTransaction transfer(String
 – Poor maintainability caused   fromAccountId, String toAccountId,
                                               ,     g             ,
   by d duplication
   b code d li i                      double amount) throws MoneyTransferException {
                                 …
 – Increased code complexity        switch (fromAccount.getOverdraftPolicy()) {
                                    case Account.NEVER:
 Fix by introducing class             …
                                      break;
                                      b   k
 hierarchy and moving               case Account.ALLOWED:
                                      …
 each part of switch                default:
                                 …
 statement into a                   }
 overriding method               }
                                   …
Data clumps
 Multiple fields or           public class A
                                bli l      Account {
                                                 t

 method parameters            public static final int NEVER = 1;
 that belong together
            g g               public static final int ALLOWED = 2;

 Consequences:                private   int id;
                              private   double balance;
 – Long methods               private   String accountId;
                              private
                              p i ate   Date dateOpened
                                              dateOpened;
 – Duplication
                              private int overdraftPolicy;
 Fix by:                      private double requiredYearsOpen;
 – Moving fields into their   private double limit;
   own class                  Account() {}
 – Eliminate resulting
                              }
   Feature Envy
Agenda
 The
 Th ups and d
           d downs of OO design
                      f    d i
 Overview of the Domain Model pattern
 Domain model b ildi bl k
 D    i    d l building blocks
 Common code smells
 Refactoring existing code
Transforming procedural code

 Inside
 I id every procedural d i i a
                   d l design is
 domain model just trying to get out
 Incrementally transform a procedural
 design into an OO design
  – Small, localized changes
  – Something to do on Monday morning!
Refactoring to an OO design
 Transform a
 procedural design to
 an OO design by
             g y
 applying refactorings
 Refactoring:
  – Restructure the code
  – Without changing
    behavior
 Essential cleanups for
 decaying code
Basic refactorings
 Extract Method
  – Eliminates long methods
 Move Method
  – Move a method to a
    different class (field or
    parameter)
  – Moves method to where
    the data i
    th d t is
 Push Down
  – Move a method into
    subclasses
  – Optionally leave an
    abstract method behind
  – Part of eliminating
                      g
    conditional logic
 …
Compound refactorings
 A sequence of simpler refactorings
 Compose method
 – Apply Extract Method repeatedly
 – Use to replace long method with more readable shorter methods
 Replace Type Code With Strategy
 – Define GOF Strategy class for each type code
                    gy                 yp
 Replace Conditional With Polymorphism
 – Turn into part of a switch statement into an overriding method in
   a subclass
 Replace Data Value with Object
 – Move field into it’s own class
 – Eliminates Primitive Obsession
DEMO
Refactoring procedural code
Summary

 Organizes the business logic as classes
 with state AND behavior
 Improves maintainability and testability
 Enabled by POJOs and non-invasive
 frameworks
 Incrementally apply by refactoring
                Use It!
For more information
   Buy my book ☺
    – Go to manning.com

   Send email:

chris@chrisrichardson.net

   Visit my website:

http://www.chrisrichardson.net
http://www chrisrichardson net

   Talk to me about consulting
   and training

Mais conteúdo relacionado

Mais procurados

Consult A Doctor Introduction
Consult A Doctor IntroductionConsult A Doctor Introduction
Consult A Doctor IntroductionADubitzky
 
Kubernetes your tests! automation with docker on google cloud platform
Kubernetes your tests! automation with docker on google cloud platformKubernetes your tests! automation with docker on google cloud platform
Kubernetes your tests! automation with docker on google cloud platformLivePerson
 
Modeling Manufacturing With Graph Databases: A Journey Towards a Digital Factory
Modeling Manufacturing With Graph Databases: A Journey Towards a Digital FactoryModeling Manufacturing With Graph Databases: A Journey Towards a Digital Factory
Modeling Manufacturing With Graph Databases: A Journey Towards a Digital FactoryNeo4j
 
Using the SugarCRM REST API
Using the SugarCRM REST APIUsing the SugarCRM REST API
Using the SugarCRM REST APIAsa Kusuma
 
Applying Network Analytics in KYC
Applying Network Analytics in KYCApplying Network Analytics in KYC
Applying Network Analytics in KYCNeo4j
 
From Generator to Fiber the Road to Coroutine in PHP
From Generator to Fiber the Road to Coroutine in PHPFrom Generator to Fiber the Road to Coroutine in PHP
From Generator to Fiber the Road to Coroutine in PHPAlbert Chen
 
Using MongoDB as a high performance graph database
Using MongoDB as a high performance graph databaseUsing MongoDB as a high performance graph database
Using MongoDB as a high performance graph databaseChris Clarke
 
FHIR API for .Net programmers by Mirjam Baltus
FHIR API for .Net programmers by Mirjam BaltusFHIR API for .Net programmers by Mirjam Baltus
FHIR API for .Net programmers by Mirjam BaltusFHIR Developer Days
 
Neptune, the Graph Database | AWS Floor28
Neptune, the Graph Database | AWS Floor28Neptune, the Graph Database | AWS Floor28
Neptune, the Graph Database | AWS Floor28Amazon Web Services
 
一生受用的統計學 大數據分析之鑰 清華大學 桑慧敏 教授
一生受用的統計學 大數據分析之鑰  清華大學 桑慧敏 教授一生受用的統計學 大數據分析之鑰  清華大學 桑慧敏 教授
一生受用的統計學 大數據分析之鑰 清華大學 桑慧敏 教授Jeffery Chi
 
Keycloak Single Sign-On
Keycloak Single Sign-OnKeycloak Single Sign-On
Keycloak Single Sign-OnRavi Yasas
 
Securing the Message Bus with Kafka Streams | Paul Otto and Ryan Salcido, Raf...
Securing the Message Bus with Kafka Streams | Paul Otto and Ryan Salcido, Raf...Securing the Message Bus with Kafka Streams | Paul Otto and Ryan Salcido, Raf...
Securing the Message Bus with Kafka Streams | Paul Otto and Ryan Salcido, Raf...HostedbyConfluent
 
The Bottom Line on Agility: Bringing FP&A and Accounting Together to Drive Tr...
The Bottom Line on Agility: Bringing FP&A and Accounting Together to Drive Tr...The Bottom Line on Agility: Bringing FP&A and Accounting Together to Drive Tr...
The Bottom Line on Agility: Bringing FP&A and Accounting Together to Drive Tr...Workday, Inc.
 
PHP 也有 Day #35 - 精通 PHP 錯誤處理,讓除錯更自在
PHP 也有 Day #35 - 精通 PHP 錯誤處理,讓除錯更自在PHP 也有 Day #35 - 精通 PHP 錯誤處理,讓除錯更自在
PHP 也有 Day #35 - 精通 PHP 錯誤處理,讓除錯更自在Asika Simon
 
Welcome to the Reactive Revolution:RSocket and Spring Cloud Gateway - Spencer...
Welcome to the Reactive Revolution:RSocket and Spring Cloud Gateway - Spencer...Welcome to the Reactive Revolution:RSocket and Spring Cloud Gateway - Spencer...
Welcome to the Reactive Revolution:RSocket and Spring Cloud Gateway - Spencer...VMware Tanzu
 

Mais procurados (18)

Consult A Doctor Introduction
Consult A Doctor IntroductionConsult A Doctor Introduction
Consult A Doctor Introduction
 
What is an API
What is an APIWhat is an API
What is an API
 
Kubernetes your tests! automation with docker on google cloud platform
Kubernetes your tests! automation with docker on google cloud platformKubernetes your tests! automation with docker on google cloud platform
Kubernetes your tests! automation with docker on google cloud platform
 
Rest api with Python
Rest api with PythonRest api with Python
Rest api with Python
 
Modeling Manufacturing With Graph Databases: A Journey Towards a Digital Factory
Modeling Manufacturing With Graph Databases: A Journey Towards a Digital FactoryModeling Manufacturing With Graph Databases: A Journey Towards a Digital Factory
Modeling Manufacturing With Graph Databases: A Journey Towards a Digital Factory
 
Using the SugarCRM REST API
Using the SugarCRM REST APIUsing the SugarCRM REST API
Using the SugarCRM REST API
 
Applying Network Analytics in KYC
Applying Network Analytics in KYCApplying Network Analytics in KYC
Applying Network Analytics in KYC
 
From Generator to Fiber the Road to Coroutine in PHP
From Generator to Fiber the Road to Coroutine in PHPFrom Generator to Fiber the Road to Coroutine in PHP
From Generator to Fiber the Road to Coroutine in PHP
 
Using MongoDB as a high performance graph database
Using MongoDB as a high performance graph databaseUsing MongoDB as a high performance graph database
Using MongoDB as a high performance graph database
 
FHIR API for .Net programmers by Mirjam Baltus
FHIR API for .Net programmers by Mirjam BaltusFHIR API for .Net programmers by Mirjam Baltus
FHIR API for .Net programmers by Mirjam Baltus
 
Pushed Authorization Requests
Pushed Authorization RequestsPushed Authorization Requests
Pushed Authorization Requests
 
Neptune, the Graph Database | AWS Floor28
Neptune, the Graph Database | AWS Floor28Neptune, the Graph Database | AWS Floor28
Neptune, the Graph Database | AWS Floor28
 
一生受用的統計學 大數據分析之鑰 清華大學 桑慧敏 教授
一生受用的統計學 大數據分析之鑰  清華大學 桑慧敏 教授一生受用的統計學 大數據分析之鑰  清華大學 桑慧敏 教授
一生受用的統計學 大數據分析之鑰 清華大學 桑慧敏 教授
 
Keycloak Single Sign-On
Keycloak Single Sign-OnKeycloak Single Sign-On
Keycloak Single Sign-On
 
Securing the Message Bus with Kafka Streams | Paul Otto and Ryan Salcido, Raf...
Securing the Message Bus with Kafka Streams | Paul Otto and Ryan Salcido, Raf...Securing the Message Bus with Kafka Streams | Paul Otto and Ryan Salcido, Raf...
Securing the Message Bus with Kafka Streams | Paul Otto and Ryan Salcido, Raf...
 
The Bottom Line on Agility: Bringing FP&A and Accounting Together to Drive Tr...
The Bottom Line on Agility: Bringing FP&A and Accounting Together to Drive Tr...The Bottom Line on Agility: Bringing FP&A and Accounting Together to Drive Tr...
The Bottom Line on Agility: Bringing FP&A and Accounting Together to Drive Tr...
 
PHP 也有 Day #35 - 精通 PHP 錯誤處理,讓除錯更自在
PHP 也有 Day #35 - 精通 PHP 錯誤處理,讓除錯更自在PHP 也有 Day #35 - 精通 PHP 錯誤處理,讓除錯更自在
PHP 也有 Day #35 - 精通 PHP 錯誤處理,讓除錯更自在
 
Welcome to the Reactive Revolution:RSocket and Spring Cloud Gateway - Spencer...
Welcome to the Reactive Revolution:RSocket and Spring Cloud Gateway - Spencer...Welcome to the Reactive Revolution:RSocket and Spring Cloud Gateway - Spencer...
Welcome to the Reactive Revolution:RSocket and Spring Cloud Gateway - Spencer...
 

Destaque

Developing polyglot persistence applications (SpringOne India 2012)
Developing polyglot persistence applications (SpringOne India 2012)Developing polyglot persistence applications (SpringOne India 2012)
Developing polyglot persistence applications (SpringOne India 2012)Chris Richardson
 
Developing modular, polyglot applications with Spring (SpringOne India 2012)
Developing modular, polyglot applications with Spring (SpringOne India 2012)Developing modular, polyglot applications with Spring (SpringOne India 2012)
Developing modular, polyglot applications with Spring (SpringOne India 2012)Chris Richardson
 
Decomposing applications for deployability and scalability (SpringOne China 2...
Decomposing applications for deployability and scalability (SpringOne China 2...Decomposing applications for deployability and scalability (SpringOne China 2...
Decomposing applications for deployability and scalability (SpringOne China 2...Chris Richardson
 
Developing polyglot persistence applications (devnexus 2013)
Developing polyglot persistence applications (devnexus 2013)Developing polyglot persistence applications (devnexus 2013)
Developing polyglot persistence applications (devnexus 2013)Chris Richardson
 
Polygot persistence for Java Developers - August 2011 / @Oakjug
Polygot persistence for Java Developers - August 2011 / @OakjugPolygot persistence for Java Developers - August 2011 / @Oakjug
Polygot persistence for Java Developers - August 2011 / @OakjugChris Richardson
 
Developing applications with Cloud Services (Devnexus 2013)
Developing applications with Cloud Services (Devnexus 2013)Developing applications with Cloud Services (Devnexus 2013)
Developing applications with Cloud Services (Devnexus 2013)Chris Richardson
 
Developing applications with Cloud Services #javaone 2012
Developing applications with Cloud Services  #javaone 2012Developing applications with Cloud Services  #javaone 2012
Developing applications with Cloud Services #javaone 2012Chris Richardson
 
Developing polyglot applications on Cloud Foundry (#oredev 2012)
Developing polyglot applications on Cloud Foundry (#oredev 2012)Developing polyglot applications on Cloud Foundry (#oredev 2012)
Developing polyglot applications on Cloud Foundry (#oredev 2012)Chris Richardson
 
Developing polyglot persistence applications #javaone 2012
Developing polyglot persistence applications  #javaone 2012Developing polyglot persistence applications  #javaone 2012
Developing polyglot persistence applications #javaone 2012Chris Richardson
 
Decomposing applications for scalability and deployability - svcc sv_code_ca...
Decomposing applications for scalability and deployability  - svcc sv_code_ca...Decomposing applications for scalability and deployability  - svcc sv_code_ca...
Decomposing applications for scalability and deployability - svcc sv_code_ca...Chris Richardson
 
Using Spring with NoSQL databases (SpringOne China 2012)
Using Spring with NoSQL databases (SpringOne China 2012)Using Spring with NoSQL databases (SpringOne China 2012)
Using Spring with NoSQL databases (SpringOne China 2012)Chris Richardson
 
Decomposing applications for scalability and deployability (devnexus 2013)
Decomposing applications for scalability and deployability (devnexus 2013)Decomposing applications for scalability and deployability (devnexus 2013)
Decomposing applications for scalability and deployability (devnexus 2013)Chris Richardson
 
Developing polyglot persistence applications (SpringOne China 2012)
Developing polyglot persistence applications (SpringOne China 2012)Developing polyglot persistence applications (SpringOne China 2012)
Developing polyglot persistence applications (SpringOne China 2012)Chris Richardson
 
Developing polyglot persistence applications (gluecon 2013)
Developing polyglot persistence applications (gluecon 2013)Developing polyglot persistence applications (gluecon 2013)
Developing polyglot persistence applications (gluecon 2013)Chris Richardson
 
NodeJS: the good parts? A skeptic’s view (jax jax2013)
NodeJS: the good parts? A skeptic’s view (jax jax2013)NodeJS: the good parts? A skeptic’s view (jax jax2013)
NodeJS: the good parts? A skeptic’s view (jax jax2013)Chris Richardson
 
Microservices pattern language (microxchg microxchg2016)
Microservices pattern language (microxchg microxchg2016)Microservices pattern language (microxchg microxchg2016)
Microservices pattern language (microxchg microxchg2016)Chris Richardson
 
Map, Flatmap and Reduce are Your New Best Friends: Simpler Collections, Concu...
Map, Flatmap and Reduce are Your New Best Friends: Simpler Collections, Concu...Map, Flatmap and Reduce are Your New Best Friends: Simpler Collections, Concu...
Map, Flatmap and Reduce are Your New Best Friends: Simpler Collections, Concu...Chris Richardson
 
Applying Domain-Driven Design to craft Rich Domain Models
Applying Domain-Driven Design to craft Rich Domain ModelsApplying Domain-Driven Design to craft Rich Domain Models
Applying Domain-Driven Design to craft Rich Domain ModelsAlexander van Trijffel
 
An Architectural Model for Adapting Domain-Specific AOM Applications
An Architectural Model for Adapting Domain-Specific AOM ApplicationsAn Architectural Model for Adapting Domain-Specific AOM Applications
An Architectural Model for Adapting Domain-Specific AOM Applicationseduardomg23
 
re:Invent 2012 Optimizing Cassandra
re:Invent 2012 Optimizing Cassandrare:Invent 2012 Optimizing Cassandra
re:Invent 2012 Optimizing CassandraRuslan Meshenberg
 

Destaque (20)

Developing polyglot persistence applications (SpringOne India 2012)
Developing polyglot persistence applications (SpringOne India 2012)Developing polyglot persistence applications (SpringOne India 2012)
Developing polyglot persistence applications (SpringOne India 2012)
 
Developing modular, polyglot applications with Spring (SpringOne India 2012)
Developing modular, polyglot applications with Spring (SpringOne India 2012)Developing modular, polyglot applications with Spring (SpringOne India 2012)
Developing modular, polyglot applications with Spring (SpringOne India 2012)
 
Decomposing applications for deployability and scalability (SpringOne China 2...
Decomposing applications for deployability and scalability (SpringOne China 2...Decomposing applications for deployability and scalability (SpringOne China 2...
Decomposing applications for deployability and scalability (SpringOne China 2...
 
Developing polyglot persistence applications (devnexus 2013)
Developing polyglot persistence applications (devnexus 2013)Developing polyglot persistence applications (devnexus 2013)
Developing polyglot persistence applications (devnexus 2013)
 
Polygot persistence for Java Developers - August 2011 / @Oakjug
Polygot persistence for Java Developers - August 2011 / @OakjugPolygot persistence for Java Developers - August 2011 / @Oakjug
Polygot persistence for Java Developers - August 2011 / @Oakjug
 
Developing applications with Cloud Services (Devnexus 2013)
Developing applications with Cloud Services (Devnexus 2013)Developing applications with Cloud Services (Devnexus 2013)
Developing applications with Cloud Services (Devnexus 2013)
 
Developing applications with Cloud Services #javaone 2012
Developing applications with Cloud Services  #javaone 2012Developing applications with Cloud Services  #javaone 2012
Developing applications with Cloud Services #javaone 2012
 
Developing polyglot applications on Cloud Foundry (#oredev 2012)
Developing polyglot applications on Cloud Foundry (#oredev 2012)Developing polyglot applications on Cloud Foundry (#oredev 2012)
Developing polyglot applications on Cloud Foundry (#oredev 2012)
 
Developing polyglot persistence applications #javaone 2012
Developing polyglot persistence applications  #javaone 2012Developing polyglot persistence applications  #javaone 2012
Developing polyglot persistence applications #javaone 2012
 
Decomposing applications for scalability and deployability - svcc sv_code_ca...
Decomposing applications for scalability and deployability  - svcc sv_code_ca...Decomposing applications for scalability and deployability  - svcc sv_code_ca...
Decomposing applications for scalability and deployability - svcc sv_code_ca...
 
Using Spring with NoSQL databases (SpringOne China 2012)
Using Spring with NoSQL databases (SpringOne China 2012)Using Spring with NoSQL databases (SpringOne China 2012)
Using Spring with NoSQL databases (SpringOne China 2012)
 
Decomposing applications for scalability and deployability (devnexus 2013)
Decomposing applications for scalability and deployability (devnexus 2013)Decomposing applications for scalability and deployability (devnexus 2013)
Decomposing applications for scalability and deployability (devnexus 2013)
 
Developing polyglot persistence applications (SpringOne China 2012)
Developing polyglot persistence applications (SpringOne China 2012)Developing polyglot persistence applications (SpringOne China 2012)
Developing polyglot persistence applications (SpringOne China 2012)
 
Developing polyglot persistence applications (gluecon 2013)
Developing polyglot persistence applications (gluecon 2013)Developing polyglot persistence applications (gluecon 2013)
Developing polyglot persistence applications (gluecon 2013)
 
NodeJS: the good parts? A skeptic’s view (jax jax2013)
NodeJS: the good parts? A skeptic’s view (jax jax2013)NodeJS: the good parts? A skeptic’s view (jax jax2013)
NodeJS: the good parts? A skeptic’s view (jax jax2013)
 
Microservices pattern language (microxchg microxchg2016)
Microservices pattern language (microxchg microxchg2016)Microservices pattern language (microxchg microxchg2016)
Microservices pattern language (microxchg microxchg2016)
 
Map, Flatmap and Reduce are Your New Best Friends: Simpler Collections, Concu...
Map, Flatmap and Reduce are Your New Best Friends: Simpler Collections, Concu...Map, Flatmap and Reduce are Your New Best Friends: Simpler Collections, Concu...
Map, Flatmap and Reduce are Your New Best Friends: Simpler Collections, Concu...
 
Applying Domain-Driven Design to craft Rich Domain Models
Applying Domain-Driven Design to craft Rich Domain ModelsApplying Domain-Driven Design to craft Rich Domain Models
Applying Domain-Driven Design to craft Rich Domain Models
 
An Architectural Model for Adapting Domain-Specific AOM Applications
An Architectural Model for Adapting Domain-Specific AOM ApplicationsAn Architectural Model for Adapting Domain-Specific AOM Applications
An Architectural Model for Adapting Domain-Specific AOM Applications
 
re:Invent 2012 Optimizing Cassandra
re:Invent 2012 Optimizing Cassandrare:Invent 2012 Optimizing Cassandra
re:Invent 2012 Optimizing Cassandra
 

Semelhante a Improving application design with a rich domain model (springone 2007)

"An introduction to object-oriented programming for those who have never done...
"An introduction to object-oriented programming for those who have never done..."An introduction to object-oriented programming for those who have never done...
"An introduction to object-oriented programming for those who have never done...Fwdays
 
Dependency injection - the right way
Dependency injection - the right wayDependency injection - the right way
Dependency injection - the right wayThibaud Desodt
 
In Visual Studios C# console app using multiple class files create a.pdf
In Visual Studios C# console app using multiple class files create a.pdfIn Visual Studios C# console app using multiple class files create a.pdf
In Visual Studios C# console app using multiple class files create a.pdfsanjeevbansal1970
 
Droid on Chain - Berry Ventura Lev, Kik
Droid on Chain - Berry Ventura Lev, KikDroid on Chain - Berry Ventura Lev, Kik
Droid on Chain - Berry Ventura Lev, KikDroidConTLV
 
Introduction to Domain driven design (LaravelBA #5)
Introduction to Domain driven design (LaravelBA #5)Introduction to Domain driven design (LaravelBA #5)
Introduction to Domain driven design (LaravelBA #5)guiwoda
 
Introduction to aop
Introduction to aopIntroduction to aop
Introduction to aopDror Helper
 
Introduction to OO, Java and Eclipse/WebSphere
Introduction to OO, Java and Eclipse/WebSphereIntroduction to OO, Java and Eclipse/WebSphere
Introduction to OO, Java and Eclipse/WebSphereeLink Business Innovations
 
Cooking your Ravioli "al dente" with Hexagonal Architecture
Cooking your Ravioli "al dente" with Hexagonal ArchitectureCooking your Ravioli "al dente" with Hexagonal Architecture
Cooking your Ravioli "al dente" with Hexagonal ArchitectureJeroen Rosenberg
 
Real Object-Oriented Programming: Empirically Validated Benefits of the DCI P...
Real Object-Oriented Programming: Empirically Validated Benefits of the DCI P...Real Object-Oriented Programming: Empirically Validated Benefits of the DCI P...
Real Object-Oriented Programming: Empirically Validated Benefits of the DCI P...James Coplien
 
Practical AngularJS
Practical AngularJSPractical AngularJS
Practical AngularJSWei Ru
 
Joining the Club: Using Spark to Accelerate Big Data at Dollar Shave Club
Joining the Club: Using Spark to Accelerate Big Data at Dollar Shave ClubJoining the Club: Using Spark to Accelerate Big Data at Dollar Shave Club
Joining the Club: Using Spark to Accelerate Big Data at Dollar Shave ClubData Con LA
 
Apex Enterprise Patterns: Building Strong Foundations
Apex Enterprise Patterns: Building Strong FoundationsApex Enterprise Patterns: Building Strong Foundations
Apex Enterprise Patterns: Building Strong FoundationsSalesforce Developers
 
Evolving a Clean, Pragmatic Architecture at JBCNConf 2019
Evolving a Clean, Pragmatic Architecture at JBCNConf 2019Evolving a Clean, Pragmatic Architecture at JBCNConf 2019
Evolving a Clean, Pragmatic Architecture at JBCNConf 2019Victor Rentea
 
Dropwizard with MongoDB and Google Cloud
Dropwizard with MongoDB and Google CloudDropwizard with MongoDB and Google Cloud
Dropwizard with MongoDB and Google CloudYun Zhi Lin
 
Fundamental Node.js (Workshop bersama Front-end Developer GITS Indonesia, War...
Fundamental Node.js (Workshop bersama Front-end Developer GITS Indonesia, War...Fundamental Node.js (Workshop bersama Front-end Developer GITS Indonesia, War...
Fundamental Node.js (Workshop bersama Front-end Developer GITS Indonesia, War...GITS Indonesia
 
Building and deploying microservices with event sourcing, CQRS and Docker (QC...
Building and deploying microservices with event sourcing, CQRS and Docker (QC...Building and deploying microservices with event sourcing, CQRS and Docker (QC...
Building and deploying microservices with event sourcing, CQRS and Docker (QC...Chris Richardson
 
So S.O.L.I.D Fu - Designing Better Code
So S.O.L.I.D Fu - Designing Better CodeSo S.O.L.I.D Fu - Designing Better Code
So S.O.L.I.D Fu - Designing Better CodeNeil Crookes
 

Semelhante a Improving application design with a rich domain model (springone 2007) (20)

"An introduction to object-oriented programming for those who have never done...
"An introduction to object-oriented programming for those who have never done..."An introduction to object-oriented programming for those who have never done...
"An introduction to object-oriented programming for those who have never done...
 
Dependency injection - the right way
Dependency injection - the right wayDependency injection - the right way
Dependency injection - the right way
 
In Visual Studios C# console app using multiple class files create a.pdf
In Visual Studios C# console app using multiple class files create a.pdfIn Visual Studios C# console app using multiple class files create a.pdf
In Visual Studios C# console app using multiple class files create a.pdf
 
Droid on Chain - Berry Ventura Lev, Kik
Droid on Chain - Berry Ventura Lev, KikDroid on Chain - Berry Ventura Lev, Kik
Droid on Chain - Berry Ventura Lev, Kik
 
Introduction to Domain driven design (LaravelBA #5)
Introduction to Domain driven design (LaravelBA #5)Introduction to Domain driven design (LaravelBA #5)
Introduction to Domain driven design (LaravelBA #5)
 
Actor Model
Actor ModelActor Model
Actor Model
 
Introduction to aop
Introduction to aopIntroduction to aop
Introduction to aop
 
Introduction to OO, Java and Eclipse/WebSphere
Introduction to OO, Java and Eclipse/WebSphereIntroduction to OO, Java and Eclipse/WebSphere
Introduction to OO, Java and Eclipse/WebSphere
 
Cooking your Ravioli "al dente" with Hexagonal Architecture
Cooking your Ravioli "al dente" with Hexagonal ArchitectureCooking your Ravioli "al dente" with Hexagonal Architecture
Cooking your Ravioli "al dente" with Hexagonal Architecture
 
Real Object-Oriented Programming: Empirically Validated Benefits of the DCI P...
Real Object-Oriented Programming: Empirically Validated Benefits of the DCI P...Real Object-Oriented Programming: Empirically Validated Benefits of the DCI P...
Real Object-Oriented Programming: Empirically Validated Benefits of the DCI P...
 
Practical AngularJS
Practical AngularJSPractical AngularJS
Practical AngularJS
 
Joining the Club: Using Spark to Accelerate Big Data at Dollar Shave Club
Joining the Club: Using Spark to Accelerate Big Data at Dollar Shave ClubJoining the Club: Using Spark to Accelerate Big Data at Dollar Shave Club
Joining the Club: Using Spark to Accelerate Big Data at Dollar Shave Club
 
Apex Enterprise Patterns: Building Strong Foundations
Apex Enterprise Patterns: Building Strong FoundationsApex Enterprise Patterns: Building Strong Foundations
Apex Enterprise Patterns: Building Strong Foundations
 
Evolving a Clean, Pragmatic Architecture at JBCNConf 2019
Evolving a Clean, Pragmatic Architecture at JBCNConf 2019Evolving a Clean, Pragmatic Architecture at JBCNConf 2019
Evolving a Clean, Pragmatic Architecture at JBCNConf 2019
 
Dropwizard with MongoDB and Google Cloud
Dropwizard with MongoDB and Google CloudDropwizard with MongoDB and Google Cloud
Dropwizard with MongoDB and Google Cloud
 
Software Engineering
Software EngineeringSoftware Engineering
Software Engineering
 
Inheritance
InheritanceInheritance
Inheritance
 
Fundamental Node.js (Workshop bersama Front-end Developer GITS Indonesia, War...
Fundamental Node.js (Workshop bersama Front-end Developer GITS Indonesia, War...Fundamental Node.js (Workshop bersama Front-end Developer GITS Indonesia, War...
Fundamental Node.js (Workshop bersama Front-end Developer GITS Indonesia, War...
 
Building and deploying microservices with event sourcing, CQRS and Docker (QC...
Building and deploying microservices with event sourcing, CQRS and Docker (QC...Building and deploying microservices with event sourcing, CQRS and Docker (QC...
Building and deploying microservices with event sourcing, CQRS and Docker (QC...
 
So S.O.L.I.D Fu - Designing Better Code
So S.O.L.I.D Fu - Designing Better CodeSo S.O.L.I.D Fu - Designing Better Code
So S.O.L.I.D Fu - Designing Better Code
 

Mais de Chris Richardson

The microservice architecture: what, why, when and how?
The microservice architecture: what, why, when and how?The microservice architecture: what, why, when and how?
The microservice architecture: what, why, when and how?Chris Richardson
 
More the merrier: a microservices anti-pattern
More the merrier: a microservices anti-patternMore the merrier: a microservices anti-pattern
More the merrier: a microservices anti-patternChris Richardson
 
YOW London - Considering Migrating a Monolith to Microservices? A Dark Energy...
YOW London - Considering Migrating a Monolith to Microservices? A Dark Energy...YOW London - Considering Migrating a Monolith to Microservices? A Dark Energy...
YOW London - Considering Migrating a Monolith to Microservices? A Dark Energy...Chris Richardson
 
Dark Energy, Dark Matter and the Microservices Patterns?!
Dark Energy, Dark Matter and the Microservices Patterns?!Dark Energy, Dark Matter and the Microservices Patterns?!
Dark Energy, Dark Matter and the Microservices Patterns?!Chris Richardson
 
Dark energy, dark matter and microservice architecture collaboration patterns
Dark energy, dark matter and microservice architecture collaboration patternsDark energy, dark matter and microservice architecture collaboration patterns
Dark energy, dark matter and microservice architecture collaboration patternsChris Richardson
 
Scenarios_and_Architecture_SkillsMatter_April_2022.pdf
Scenarios_and_Architecture_SkillsMatter_April_2022.pdfScenarios_and_Architecture_SkillsMatter_April_2022.pdf
Scenarios_and_Architecture_SkillsMatter_April_2022.pdfChris Richardson
 
Using patterns and pattern languages to make better architectural decisions
Using patterns and pattern languages to make better architectural decisions Using patterns and pattern languages to make better architectural decisions
Using patterns and pattern languages to make better architectural decisions Chris Richardson
 
iSAQB gathering 2021 keynote - Architectural patterns for rapid, reliable, fr...
iSAQB gathering 2021 keynote - Architectural patterns for rapid, reliable, fr...iSAQB gathering 2021 keynote - Architectural patterns for rapid, reliable, fr...
iSAQB gathering 2021 keynote - Architectural patterns for rapid, reliable, fr...Chris Richardson
 
Events to the rescue: solving distributed data problems in a microservice arc...
Events to the rescue: solving distributed data problems in a microservice arc...Events to the rescue: solving distributed data problems in a microservice arc...
Events to the rescue: solving distributed data problems in a microservice arc...Chris Richardson
 
A pattern language for microservices - June 2021
A pattern language for microservices - June 2021 A pattern language for microservices - June 2021
A pattern language for microservices - June 2021 Chris Richardson
 
QConPlus 2021: Minimizing Design Time Coupling in a Microservice Architecture
QConPlus 2021: Minimizing Design Time Coupling in a Microservice ArchitectureQConPlus 2021: Minimizing Design Time Coupling in a Microservice Architecture
QConPlus 2021: Minimizing Design Time Coupling in a Microservice ArchitectureChris Richardson
 
Mucon 2021 - Dark energy, dark matter: imperfect metaphors for designing micr...
Mucon 2021 - Dark energy, dark matter: imperfect metaphors for designing micr...Mucon 2021 - Dark energy, dark matter: imperfect metaphors for designing micr...
Mucon 2021 - Dark energy, dark matter: imperfect metaphors for designing micr...Chris Richardson
 
Designing loosely coupled services
Designing loosely coupled servicesDesigning loosely coupled services
Designing loosely coupled servicesChris Richardson
 
Microservices - an architecture that enables DevOps (T Systems DevOps day)
Microservices - an architecture that enables DevOps (T Systems DevOps day)Microservices - an architecture that enables DevOps (T Systems DevOps day)
Microservices - an architecture that enables DevOps (T Systems DevOps day)Chris Richardson
 
DDD SoCal: Decompose your monolith: Ten principles for refactoring a monolith...
DDD SoCal: Decompose your monolith: Ten principles for refactoring a monolith...DDD SoCal: Decompose your monolith: Ten principles for refactoring a monolith...
DDD SoCal: Decompose your monolith: Ten principles for refactoring a monolith...Chris Richardson
 
Decompose your monolith: Six principles for refactoring a monolith to microse...
Decompose your monolith: Six principles for refactoring a monolith to microse...Decompose your monolith: Six principles for refactoring a monolith to microse...
Decompose your monolith: Six principles for refactoring a monolith to microse...Chris Richardson
 
TDC2020 - The microservice architecture: enabling rapid, reliable, frequent a...
TDC2020 - The microservice architecture: enabling rapid, reliable, frequent a...TDC2020 - The microservice architecture: enabling rapid, reliable, frequent a...
TDC2020 - The microservice architecture: enabling rapid, reliable, frequent a...Chris Richardson
 
Overview of the Eventuate Tram Customers and Orders application
Overview of the Eventuate Tram Customers and Orders applicationOverview of the Eventuate Tram Customers and Orders application
Overview of the Eventuate Tram Customers and Orders applicationChris Richardson
 
An overview of the Eventuate Platform
An overview of the Eventuate PlatformAn overview of the Eventuate Platform
An overview of the Eventuate PlatformChris Richardson
 
#DevNexus202 Decompose your monolith
#DevNexus202 Decompose your monolith#DevNexus202 Decompose your monolith
#DevNexus202 Decompose your monolithChris Richardson
 

Mais de Chris Richardson (20)

The microservice architecture: what, why, when and how?
The microservice architecture: what, why, when and how?The microservice architecture: what, why, when and how?
The microservice architecture: what, why, when and how?
 
More the merrier: a microservices anti-pattern
More the merrier: a microservices anti-patternMore the merrier: a microservices anti-pattern
More the merrier: a microservices anti-pattern
 
YOW London - Considering Migrating a Monolith to Microservices? A Dark Energy...
YOW London - Considering Migrating a Monolith to Microservices? A Dark Energy...YOW London - Considering Migrating a Monolith to Microservices? A Dark Energy...
YOW London - Considering Migrating a Monolith to Microservices? A Dark Energy...
 
Dark Energy, Dark Matter and the Microservices Patterns?!
Dark Energy, Dark Matter and the Microservices Patterns?!Dark Energy, Dark Matter and the Microservices Patterns?!
Dark Energy, Dark Matter and the Microservices Patterns?!
 
Dark energy, dark matter and microservice architecture collaboration patterns
Dark energy, dark matter and microservice architecture collaboration patternsDark energy, dark matter and microservice architecture collaboration patterns
Dark energy, dark matter and microservice architecture collaboration patterns
 
Scenarios_and_Architecture_SkillsMatter_April_2022.pdf
Scenarios_and_Architecture_SkillsMatter_April_2022.pdfScenarios_and_Architecture_SkillsMatter_April_2022.pdf
Scenarios_and_Architecture_SkillsMatter_April_2022.pdf
 
Using patterns and pattern languages to make better architectural decisions
Using patterns and pattern languages to make better architectural decisions Using patterns and pattern languages to make better architectural decisions
Using patterns and pattern languages to make better architectural decisions
 
iSAQB gathering 2021 keynote - Architectural patterns for rapid, reliable, fr...
iSAQB gathering 2021 keynote - Architectural patterns for rapid, reliable, fr...iSAQB gathering 2021 keynote - Architectural patterns for rapid, reliable, fr...
iSAQB gathering 2021 keynote - Architectural patterns for rapid, reliable, fr...
 
Events to the rescue: solving distributed data problems in a microservice arc...
Events to the rescue: solving distributed data problems in a microservice arc...Events to the rescue: solving distributed data problems in a microservice arc...
Events to the rescue: solving distributed data problems in a microservice arc...
 
A pattern language for microservices - June 2021
A pattern language for microservices - June 2021 A pattern language for microservices - June 2021
A pattern language for microservices - June 2021
 
QConPlus 2021: Minimizing Design Time Coupling in a Microservice Architecture
QConPlus 2021: Minimizing Design Time Coupling in a Microservice ArchitectureQConPlus 2021: Minimizing Design Time Coupling in a Microservice Architecture
QConPlus 2021: Minimizing Design Time Coupling in a Microservice Architecture
 
Mucon 2021 - Dark energy, dark matter: imperfect metaphors for designing micr...
Mucon 2021 - Dark energy, dark matter: imperfect metaphors for designing micr...Mucon 2021 - Dark energy, dark matter: imperfect metaphors for designing micr...
Mucon 2021 - Dark energy, dark matter: imperfect metaphors for designing micr...
 
Designing loosely coupled services
Designing loosely coupled servicesDesigning loosely coupled services
Designing loosely coupled services
 
Microservices - an architecture that enables DevOps (T Systems DevOps day)
Microservices - an architecture that enables DevOps (T Systems DevOps day)Microservices - an architecture that enables DevOps (T Systems DevOps day)
Microservices - an architecture that enables DevOps (T Systems DevOps day)
 
DDD SoCal: Decompose your monolith: Ten principles for refactoring a monolith...
DDD SoCal: Decompose your monolith: Ten principles for refactoring a monolith...DDD SoCal: Decompose your monolith: Ten principles for refactoring a monolith...
DDD SoCal: Decompose your monolith: Ten principles for refactoring a monolith...
 
Decompose your monolith: Six principles for refactoring a monolith to microse...
Decompose your monolith: Six principles for refactoring a monolith to microse...Decompose your monolith: Six principles for refactoring a monolith to microse...
Decompose your monolith: Six principles for refactoring a monolith to microse...
 
TDC2020 - The microservice architecture: enabling rapid, reliable, frequent a...
TDC2020 - The microservice architecture: enabling rapid, reliable, frequent a...TDC2020 - The microservice architecture: enabling rapid, reliable, frequent a...
TDC2020 - The microservice architecture: enabling rapid, reliable, frequent a...
 
Overview of the Eventuate Tram Customers and Orders application
Overview of the Eventuate Tram Customers and Orders applicationOverview of the Eventuate Tram Customers and Orders application
Overview of the Eventuate Tram Customers and Orders application
 
An overview of the Eventuate Platform
An overview of the Eventuate PlatformAn overview of the Eventuate Platform
An overview of the Eventuate Platform
 
#DevNexus202 Decompose your monolith
#DevNexus202 Decompose your monolith#DevNexus202 Decompose your monolith
#DevNexus202 Decompose your monolith
 

Ú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 Servicegiselly40
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024The Digital Insurer
 
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 MenDelhi Call girls
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
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 MenDelhi Call girls
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...Neo4j
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
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 organizationRadu Cotescu
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
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...Enterprise Knowledge
 
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 interpreternaman860154
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilV3cube
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsRoshan Dwivedi
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 

Último (20)

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
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
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
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
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
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
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
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
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...
 
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
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of Brazil
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 

Improving application design with a rich domain model (springone 2007)

  • 1. 20 – 22 June 2007 Metropolis Antwerp, Belgium
  • 2. Improving Applications Design with a Rich Domain Model Chris Richardson Author of POJOs in Action www.chrisrichardson.net
  • 3. About Chris Grew up in England Live in Oakland, CA Twenty years of software development experience – Building object-oriented software since 1986 – Using Java since 1996 – Using J2EE since 1999 Author of POJOs in Action Speaker at JavaOne, JavaPolis, NFJS, JUGs, …. Chair of the eBIG Java SIG in Oakland (www ebig org) (www.ebig.org) Run a consulting and training company that helps organizations build better software faster
  • 4. Overall presentation goal Learn how to improve application design with truly object-oriented business logic
  • 5. Agenda The Th ups and d d downs of OO design f d i Overview of the Domain Model pattern Domain model building blocks Common code smells Refactoring existing code
  • 6. Designing business logic Spring promotes good design practices: – Dependency injection for loose coupling – AOP for handling cross cutting concerns But you must decide how to structure your business logic: – Domain Model pattern – object-oriented – Transaction Script pattern – procedural Choice of pattern impacts ease of: – Development testing maintainability …. Development, testing, maintainability,
  • 7. Lots of procedural Java code Java is an object oriented language object-oriented AND Object-oriented design is a better way to tackle complexity YET Many complex enterprise Java applications are written in a procedural style
  • 10. Example procedural code public class MoneyTransferServiceProceduralImpl implements MoneyTransferService { public class Account { p public BankingTransaction transfer(String fromAccountId, String toAccountId, g ( g , g , p public static final int NEVER = 1; ; double amount) throws MoneyTransferException { public static final int ALLOWED = 2; Account fromAccount = accountDAO.findAccount(fromAccountId); Account toAccount = accountDAO.findAccount(toAccountId); private int id; assert amount > 0; private double balance; double newBalance = fromAccount.getBalance() - amount; private int overdraftPolicy; switch (fromAccount.getOverdraftPolicy()) { private String accountId; case Account.NEVER: private Date dateOpened; if (newBalance < 0) private double requiredYearsOpen; throw new MoneyTransferException("In sufficient funds"); private double limit; break; case Account.ALLOWED: Account() {} Calendar then = Calendar.getInstance(); then.setTime(fromAccount.getDateOpened()); Calendar now = Calendar.getInstance(); public Account(String accountId, double balance, int overdraftPolicy, double yearsOpened = now.get(Calendar.YEAR) - then.get(Calendar.YEAR); Date dateOpened, double requiredYearsOpen, int monthsOpened = now.get(Calendar.MONTH) - then.get(Calendar.MONTH); double limit) if (monthsOpened < 0) { {….. } yearsOpened--; O d monthsOpened += 12; public int getId() {return id;} } yearsOpened = yearsOpened + (monthsOpened / 12.0); public String getAccountId() {return accountId;} if (yearsOpened < fromAccount.getRequiredYearsOpen() || newBalance < fromAccount.getLimit()) public void setBalance(double balance) { this.balance = balance; } throw new MoneyTransferException("Limit exceeded"); break; public double getBalance() { return balance; } default: throw new MoneyTransferException( Unknown overdraft type: " MoneyTransferException("Unknown public int getOverdraftPolicy() { return overdraftPolicy; } + fromAccount.getOverdraftPolicy()); public Date getDateOpened() { return dateOpened; } } fromAccount.setBalance(newBalance); public double getRequiredYearsOpen() { toAccount.setBalance(toAccount.getBalance() + amount); return requiredYearsOpen; } TransferTransaction txn = new TransferTransaction(fromAccount, toAccount, amount, new Date()); public double getLimit() {return limit; } bankingTransactionDAO.addTransaction(txn); } return txn; }
  • 11. A seductive programming style Implementing new f I l ti functionality i easy ti lit is – Add a new transaction script – Add code to a new transaction script No need to do any real design, e.g. – Create new classes – Determine responsibilities p
  • 12. Unable to handle complexity Works well for simple business logic – E.g. the example wasn’t that bad But with complex business logic: – Large transaction scripts: 100s/1000s LOC – Difficult/impossible to understand, test, and maintain What’s worse: business logic has a habit of growing – New requirements ⇒ Add a few more lines to the transaction script – Many new requirements ⇒ big mess
  • 13. Today – OO is growing in popularity POJOs – Plain Old Java Objects – Leverage OO features of Java O/R mapping frameworks for persisting POJO i ti POJOs: – Hibernate – Java Persistence API – … Spring AOP and AspectJ for handling cross-cutting concerns: – Transaction management – Security – Logging – Auditing – …
  • 14. Agenda The Th ups and d d downs of OO design f d i Overview of the Domain Model pattern Domain model building blocks Common code smells Refactoring existing code
  • 15. Using the Domain Model Pattern Business l i spread amongst a collection of B i logic d t ll ti f classes Many classes correspond to real world concepts: Order, Customer, … Many classes are true objects having both: – State – fields – Behavior – methods that act on the state
  • 19. Benefits of the Domain Model Pattern Improved maintainability – The design reflects reality – The design is more modular Improved testability – Small classes that can be tested in isolation Improved reusability – Classes can be used in other applications Building a domain model g – Creates shared understanding – Develops an ubiquitous language
  • 20. Quantifiably simpler methods Procedural – few, longer, more Object-oriented – more, complex methods simpler, simpler shorter methods
  • 21. Drawbacks of the Domain Model pattern Requires object-oriented d i skills R i bj t i t d design kill Requires domain model to be transparently “mappable” to the data – E.g. nice database schema – Ugly schemas and data stored in other applications is a challenge
  • 22. When to use it The b i Th business l i i reasonably complex logic is bl l or you anticipate that it will be You have the skills to design one You can use an ORM framework
  • 23. Agenda The Th ups and d d downs of OO design f d i Overview of the Domain Model pattern Domain model building blocks Common code smells Refactoring existing code
  • 24. Domain model building blocks Roles k R l aka stereotypes Benefits of roles: – Guide design – Help name objects – Aid understanding Roles (from Domain- Domain Driven Design)
  • 25. Entity public class Account { Objects ith di ti t Obj t with a distinct private int id; identity private double balance; private OverdraftPolicy overdraftPolicy; Typically correspond private String accountId; private CalendarDate dateOpened; to real world concepts Account() { } Almost always public void debit(double amount) throws MoneyTransferException { assert amount > 0; double originalBalance = balance; persistent double newBalance = balance - amount; overdraftPolicy.beforeDebitCheck(this, originalBalance, newBalance); balance = newBalance; overdraftPolicy.afterDebitAction(this, originalBalance, newBalance); } public void credit(double amount) { assert amount > 0; balance += amount; }
  • 26. Value Objects Objects that are public class CalendarDate { private Date date; defined by the values CalendarDate() { } of their attributes public CalendarDate(Date date) { this.date = date; Two instances with } public Date getDate() { identical values can } return date; be b used d public double getYearsOpen() { Calendar then = Calendar.getInstance(); then.setTime(date); interchangeably Calendar now = Calendar.getInstance(); int yearsOpened = now.get(Calendar.YEAR) – Often immutable and then.get(Calendar.YEAR); int monthsOpened = now.get(Calendar.MONTH) - then.get(Calendar.MONTH); persistent if (monthsOpened < 0) { yearsOpened--; monthsOpened += 12; } Part of an entityy return yearsOpened + (monthsOpened/12.0); } }
  • 27. Aggregates A cluster of related entities and values Behaves as a unit Has a root Has a bou da y as boundary Objects outside the aggregate can only reference the root f Deleting the root removes everything
  • 28. Repositories public interface AccountRepository { Manages a collection of Account findAccount(String accountId); objects void addAccount(Account account); Provides methods for: } Adding an object public class HibernateAccountRepository implements AccountRepository { Finding object or objects private HibernateTemplate hibernateTemplate; Deleting objects public HibernateAccountRepository(HibernateTemplate template) { hibernateTemplate = template; p p Consists of an interface and an } implementation class public void addAccount(Account account) { hibernateTemplate.save(account); Encapsulates database access } mechanism public Account findAccount(final String accountId) { return (Account) DataAccessUtils.uniqueResult(hibernateTemplate .findByNamedQueryAndNamedParam( Keeps the ORM framework out "Account.findAccountByAccountId", "accountId", accountId)); of the domain model } Similar to a DAO }
  • 29. Services public interface MoneyTransferService { Implements logic that cannot BankingTransaction transfer(String fromAccountId, be put in a single entity String toAccountId, double amount) throws MoneyTransferException; Not persistent } Consists of an interface and an implementation class public class MoneyTransferServiceImpl implements MoneyTransferService { Service method usually: private final AccountRepository accountRepository; Invoked (indirectly) by p private final BankingTransactionRepository g p bankingTransactionRepository; y presentation tier public MoneyTransferServiceImpl(AccountRepository accountRepository, BankingTransactionRepository bankingTransactionRepository) { Invokes one or more this.accountRepository = accountRepository; this.bankingTransactionRepository = bankingTransactionRepository; repositories } Invokes one or more entities public BankingTransaction transfer(String fromAccountId, String toAccountId, double amount) { … Keep them thin } }
  • 30. Factories Use when a constructor is insufficient – Encapsulates complex object creation logic – Varying products Different kinds of factories –F t Factory classes l – Factory methods Example: O d F t E l OrderFactory – Creates Order from a shopping cart – Add li it Adds line items
  • 31. Role of Spring 1 Use the U th POJO programming model i d l – Minimize dependencies on infrastructure frameworks: your domain model might outlive them – Avoid @DoThisAnnotations: e.g. @Transactional Spring instantiates and wires together – Services, factories and repositories Dependency injection into entities p y j – One option is @Configurable but it’s not POJO – Hibernate Interceptor/Manual injection is preferable
  • 32. Role of Spring 2 Spring S i AOP for service-level crosscutting f i l l tti concerns: – E g transaction management, security logging etc E.g. management security, etc. AspectJ for entity and value object crosscutting concerns – E.g. tracking changes to fields – AJC/Load-time weaving has a cost g Use Spring ORM in the repository implementation classes
  • 33. Agenda The Th ups and d d downs of OO design f d i Overview of the Domain Model pattern Domain model building blocks Common code smells Refactoring existing code
  • 34. Overview of code smells Code C d smell = something about th code ll thi b t the d that does not seem right Impacts ease of development and testing Some are non-OOD Some are the consequences of non-OOD
  • 35. Long method Methods should be short p public class MoneyTransferServiceProceduralImpl implements MoneyTransferService { y p p y public BankingTransaction transfer(String fromAccountId, String toAccountId, double amount) throws MoneyTransferException { Account fromAccount = accountDAO.findAccount(fromAccountId); But business logic is Account toAccount = accountDAO.findAccount(toAccountId); assert amount > 0; double newBalance = fromAccount.getBalance() - amount; concentrated in the switch (fromAccount.getOverdraftPolicy()) { case Account.NEVER: if (newBalance < 0) services ⇒ l throw new MoneyTransferException( In sufficient funds"); MoneyTransferException("In funds ); i long methods th d break; case Account.ALLOWED: Calendar then = Calendar.getInstance(); then.setTime(fromAccount.getDateOpened()); Long methods are difficult Calendar now = Calendar.getInstance(); double yearsOpened = now.get(Calendar.YEAR) - then.get(Calendar.YEAR); int monthsOpened = now.get(Calendar.MONTH) - then.get(Calendar.MONTH); to: if (monthsOpened < 0) { yearsOpened--; monthsOpened += 12 th O d + 12; } – Read and understand yearsOpened = yearsOpened + (monthsOpened / 12.0); if (yearsOpened < fromAccount.getRequiredYearsOpen() || newBalance < fromAccount.getLimit()) throw new MoneyTransferException("Limit exceeded"); – Maintain break; default: throw new MoneyTransferException("Unknown overdraft type: " – Test } + fromAccount.getOverdraftPolicy()); fromAccount.setBalance(newBalance); Fix: toAccount.setBalance(toAccount.getBalance() + amount); TransferTransaction txn = new TransferTransaction(fromAccount, toAccount, amount, new Date()); bankingTransactionDAO.addTransaction(txn); return txn; – Splitting into smaller } methods
  • 36. Feature Envy Methods that are far p public class MoneyTransferServiceProceduralImpl implements MoneyTransferService { y p p y public BankingTransaction transfer(String fromAccountId, String toAccountId, double amount) throws MoneyTransferException { Account fromAccount = accountDAO.findAccount(fromAccountId); too interested in data Account toAccount = accountDAO.findAccount(toAccountId); assert amount > 0; double newBalance = fromAccount.getBalance() - amount; switch (fromAccount.getOverdraftPolicy()) { belonging to other g g case Account.NEVER: if (newBalance < 0) throw new MoneyTransferException( In sufficient funds"); break; MoneyTransferException("In funds ); classes case Account.ALLOWED: Calendar then = Calendar.getInstance(); then.setTime(fromAccount.getDateOpened()); Calendar now = Calendar.getInstance(); Results in: double yearsOpened = now.get(Calendar.YEAR) - then.get(Calendar.YEAR); int monthsOpened = now.get(Calendar.MONTH) - then.get(Calendar.MONTH); if (monthsOpened < 0) { yearsOpened--; monthsOpened += 12 th O d + 12; – Poor encapsulation } yearsOpened = yearsOpened + (monthsOpened / 12.0); if (yearsOpened < fromAccount.getRequiredYearsOpen() || newBalance < fromAccount.getLimit()) – Long methods throw new MoneyTransferException("Limit exceeded"); break; default: throw new MoneyTransferException("Unknown overdraft type: " + fromAccount.getOverdraftPolicy()); Fix by moving } fromAccount.setBalance(newBalance); toAccount.setBalance(toAccount.getBalance() + amount); methods to the class TransferTransaction txn = new TransferTransaction(fromAccount, toAccount, amount, new Date()); bankingTransactionDAO.addTransaction(txn); return txn; that has the data }
  • 37. Data class public class Account { Classes that are j t Cl th t just public static final int NEVER = 1; public static final int ALLOWED = 2; getters and setters private private int id; double balance; private int overdraftPolicy; No business logic - private private private String accountId; Date dateOpened; double requiredYearsOpen; private double limit; it’s in the service Account() {} Leads to: public Account(String accountId, double balance, int overdraftPolicy, {….. } Date dateOpened, double requiredYearsOpen, double limit) – Feature envy public int getId() {return id;} public String getAccountId() {return accountId;} Fix by moving public void setBalance(double balance) { this.balance = balance; } public double getBalance() { return balance; } methods that act on public int getOverdraftPolicy() { return overdraftPolicy; } public Date getDateOpened() { return dateOpened; } data into class public double getRequiredYearsOpen() { return requiredYearsOpen; } public double getLimit() {return limit; } }
  • 38. Primitive Obsession public class Account { private Date dateOpened; Code uses built in built-in } types instead of public class Account { private Date dateOpened; application classes } public class MoneyTransferServiceProceduralImpl implements Consequences: C MoneyTransferService { public BankingTransaction transfer(String fromAccountId, String – Reduces toAccountId, double amount) throws MoneyTransferException { understandability Account fromAccount = accountDAO.findAccount(fromAccountId); Account toAccount = accountDAO findAccount(toAccountId); accountDAO.findAccount(toAccountId); – L Long methods h d … Calendar then = Calendar.getInstance(); – Code duplication then.setTime(fromAccount.getDateOpened()); Calendar now = Calendar.getInstance(); – Added complexity double yearsOpened = now.get(Calendar.YEAR) - then.get(Calendar.YEAR); int monthsOpened = now.get(Calendar.MONTH) – Fix by moving data then.get(Calendar.MONTH); if (monthsOpened < 0) { and code into new yearsOpened--; monthsOpened += 12; class } yea sOpe ed yearsOpened = yea sOpe ed + (monthsOpened / 12.0); yearsOpened ( o t sOpe ed 0); if (yearsOpened < fromAccount.getRequiredYearsOpen() || newBalance < fromAccount.getLimit()) … }
  • 39. Switch Statements public class Account { Use of type codes and public static final int NEVER = 1; switch statements instead public static final int ALLOWED = 2; … of polymorphism Consequences: C public class MoneyTransferServiceProceduralImpl implements MoneyTransferService { – Longer methods public BankingTransaction transfer(String – Poor maintainability caused fromAccountId, String toAccountId, , g , by d duplication b code d li i double amount) throws MoneyTransferException { … – Increased code complexity switch (fromAccount.getOverdraftPolicy()) { case Account.NEVER: Fix by introducing class … break; b k hierarchy and moving case Account.ALLOWED: … each part of switch default: … statement into a } overriding method } …
  • 40. Data clumps Multiple fields or public class A bli l Account { t method parameters public static final int NEVER = 1; that belong together g g public static final int ALLOWED = 2; Consequences: private int id; private double balance; – Long methods private String accountId; private p i ate Date dateOpened dateOpened; – Duplication private int overdraftPolicy; Fix by: private double requiredYearsOpen; – Moving fields into their private double limit; own class Account() {} – Eliminate resulting } Feature Envy
  • 41. Agenda The Th ups and d d downs of OO design f d i Overview of the Domain Model pattern Domain model b ildi bl k D i d l building blocks Common code smells Refactoring existing code
  • 42. Transforming procedural code Inside I id every procedural d i i a d l design is domain model just trying to get out Incrementally transform a procedural design into an OO design – Small, localized changes – Something to do on Monday morning!
  • 43. Refactoring to an OO design Transform a procedural design to an OO design by g y applying refactorings Refactoring: – Restructure the code – Without changing behavior Essential cleanups for decaying code
  • 44. Basic refactorings Extract Method – Eliminates long methods Move Method – Move a method to a different class (field or parameter) – Moves method to where the data i th d t is Push Down – Move a method into subclasses – Optionally leave an abstract method behind – Part of eliminating g conditional logic …
  • 45. Compound refactorings A sequence of simpler refactorings Compose method – Apply Extract Method repeatedly – Use to replace long method with more readable shorter methods Replace Type Code With Strategy – Define GOF Strategy class for each type code gy yp Replace Conditional With Polymorphism – Turn into part of a switch statement into an overriding method in a subclass Replace Data Value with Object – Move field into it’s own class – Eliminates Primitive Obsession
  • 47. Summary Organizes the business logic as classes with state AND behavior Improves maintainability and testability Enabled by POJOs and non-invasive frameworks Incrementally apply by refactoring Use It!
  • 48. For more information Buy my book ☺ – Go to manning.com Send email: chris@chrisrichardson.net Visit my website: http://www.chrisrichardson.net http://www chrisrichardson net Talk to me about consulting and training