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()