add_entity makes it easy to create a class that encapsulates the data
and behaviours of an Entity in a domain.
add_entity(name, domain, commands = NULL, queries = NULL)
| name | (  | 
    
|---|---|
| domain | (  | 
    
| commands | (  | 
    
| queries | (  | 
    
add_entity do?Given the Entity name, and its domain name, and optionally
commands and queries methods,
When add_entity is called
add_entity(name = 'Order', domain = 'Pizza Ordering', commands = 'add_item_to_order', queries = 'review_order')
Then the function:
Generates boilerplate code for the Entity and saves it at R/pizza_ordering-entity-Order.R;
Generates a unit-test for the Entity and saves it at tests/testthat/test-pizza_ordering-entity-Order.R; and
Opens the files (only in interactive mode).
Tip: You don’t need to remember the naming style for the different DDD components.
Instead, ddd takes care of naming style for all domain
objects.
This way DDD file names, classes and functions are congruent with each other.
The boilerplate code for the Order Entity class produced by add_entity
looks like this:
R/pizza_ordering-entity-Order.R
#' @title Order Domain Entity #' @family Pizza Ordering #' @noRd Order <- R6::R6Class("Order", inherit = AbstractEntity, lock_objects = FALSE, cloneable = FALSE) # Public Methods ---------------------------------------------------------- Order$set("public", "initialize", overwrite = TRUE, function(uid){ super$initialize(uid) return(self) }) Order$set(which = "public", overwrite = TRUE, name = "add_item_to_order", value = function(...){ # TODO: Write command code here return(self) }) Order$set(which = "public", overwrite = TRUE, name = "review_order", value = function(){ # TODO: Write query code here query_result <- mtcars return(query_result) })
Notice the three public methods created by add_entity:
initialize is a constructor for new entities.
By DDD definition, every Entity must have a unique id (uid)
which distinguishes it from other Entities.
add_item_to_order is a command boilerplate. You’ll need to:
Replace ... with explicit (if any) input arguments; and
Implement the method behaviour. Remember, command doesn’t return data.
review_order is a query boilerplate. You’ll need to:
Replace its content to retrieve data from the object
Remember, query does not change the state of the system.
The boilerplate code for the Order Entity unit-test produced by
add_entity looks like this:
tests/testthat/test-pizza_ordering-entity-Order.R
context('unit test for entity Order') # Setup ------------------------------------------------------------------- entity_uid <- "738a742a" # General ----------------------------------------------------------------- test_that('calling Order$new instantiates an object with a unique id', { expect_s3_class(entity <<- Order$new(uid = entity_uid), "Order") }) # Public Methods ---------------------------------------------------------- test_that('calling add_item_to_order changes the state of the object', { expect_s3_class(entity$add_item_to_order(), "Order") }) test_that('calling review_order returns the desired results', { expect_equivalent(entity$review_order(), mtcars) })
Optional: Call ddd::use_ddd maximum once per project; this will
make the project independent of ddd
Call ddd::add_entity with its respective arguments
Call devtools::document (or Ctrl+Shift+D on windows) to include
the Entity in the project NAMESPACE file
Call devtools::test (or Ctrl+Shift+T on windows) to validate that
the Entity’s unit-test pass
Other domain object generators: 
add_domain_service(),
add_value_object()