(Video included as last slide. Also available at https://www.youtube.com/watch?v=ogjOKlXHi08)
What are the basic blocks of which you build a domain? It is probably not integers, strings, and floats. Instead it might be things such as “room number,” “track,” or “time slot.” They might be simple, they might be complex, but they are the simplest things that still makes sense in your domain - these are your domain primitives.
Obviously, value objects are a feasible way of implementing many domain primitives. But certainly not all value objects are primitives. In this session, we’ll dive into what domain primitives are and how they enable solutions that make your code secure by design. In addition, we’ll show how domain primitives in combination with context mapping gives a powerful way to clean up legacy code. We cover some concrete patterns that you can start using immediately.
This presentation is partly based on material from upcoming book Secure by Design by Dan Bergh Johnsson, Daniel Deogun, and Daniel Sawano.
Diamond Application Development Crafting Solutions with Precision
Domain Primitives In Action - Explore DDD 2017
1. Domain Primitives in Action
- Making it Secure by Design
@DanielDeogun @danbjson
Explore DDD, Denver 2017
2. @DanielDeogun @danbjson #SecureByDesign #EDDD
About Us…
Dan Bergh Johnsson
Secure Domain Philosopher
Omegapoint, Sweden
Umeå
Malmö
Göteborg
Falun
New York
Stockholm
Daniel Deogun
Coder and Quality Defender
3. @DanielDeogun @danbjson #SecureByDesign #EDDD
Key Take Aways
Domain Primitives
- are native to your domain
- form a conceptual whole
- easy way to improve and secure existing code
5. @DanielDeogun @danbjson #SecureByDesign #EDDD
Peano's Axioms
1. Zero is a number
2. If n is a number, the successor of n is a number
3. Zero isn’t the successor of a number
4. Two numbers of which the successors are equal are themselves equal
5. If a set S of numbers contains zero and also the successor of every
number in S, then every number is in S
Abelian group
• Closure: a + b = integer
• Associativity: a + (b + c) = (a + b) + c
• Commutativity: a + b = b + a
• Identity: a + 0 = a
• Inverse: a + (−a) = 0
It’s “just” an Integer?
7. @DanielDeogun @danbjson #SecureByDesign #EDDD
Math and Hotel are
different Contexts
Math Domain
Integer
Hotel Domain
Room Number
Hotel Domain
Math Domain
Integer
(a.k.a Room Number)
8. @DanielDeogun @danbjson #SecureByDesign #EDDD
Room Number
public final class RoomNumber {
private final int value;
public RoomNumber(final int value) {
isTrue(Floor.isValid(value));
inclusiveBetween(1, 50, value % 100);
this.value = value;
}
public Floor floor() {
return new Floor(value);
}
// other logic …
}
9. @DanielDeogun @danbjson #SecureByDesign #EDDD
Definition of
Domain Primitive
• Building block that’s native to your domain
• Valid in your context
• Immutable and resemble a value object
“A value object so precise in its definition that it, by its mere
existence, manifests its validity is called a Domain Primitive.”
- Secure by Design
10. @DanielDeogun @danbjson #SecureByDesign #EDDD
Less Simple
Domain Primitive
public void pay(final double money, final int recipientId) {
final String currency = CurrencyService.currencyFor(recipientId);
BankService.transfer(money, currency, recipientId);
}
public void pay(final Money money, final Recipient recipient) {
notNull(money);
notNull(recipient);
BankService.transfer(money, recipient);
}
But Money is a conceptual whole and
should be modeled as a domain primitive
11. @DanielDeogun @danbjson #SecureByDesign #EDDD
Intelligent Machines -
not just values
class Rate {
private final Currency from;
private final Currency to;
Rate(Currency from, Currency to) {
this.from = notNull(from);
this.to = notNull(to);
}
Money exchange(Money from) {
notNull(from);
isTrue(this.from
.equals(from.currency));
BigDecimal converted = . . .
return new Money(converted, to);
}
}
12. @DanielDeogun @danbjson #SecureByDesign #EDDD
Standing on the
Shoulders of Giants
• Domain Primitives act as building blocks
• Guy L. Steele Jr. “Growing a Language”
• Abelson, Sussman “Structure and
Interpretation of Computer Programs”
https://flic.kr/p/8cc44h https://creativecommons.org/licenses/by/2.0/
13. @DanielDeogun @danbjson #SecureByDesign #EDDD
… In Action
https://flic.kr/p/Q7zV https://creativecommons.org/licenses/by-sa/2.0/
vs
https://flic.kr/p/djYc9H https://creativecommons.org/licenses/by/2.0/
Green Field Brown Field
14. @DanielDeogun @danbjson #SecureByDesign #EDDD
“Draw the Line”
- Find a Semantic Border
https://flic.kr/p/nEZKMd https://creativecommons.org/licenses/by/2.0/
public void checkout(final int roomNumber) {
new RoomNumber(roomNumber); //throws exception if invalid
houseKeepingService.registerForCleaning(roomNumber);
minibarService.replenish(roomNumber);
// other operations ...
}
public void checkout(final int roomNumber) {
if (!RoomNumber.isValid(roomNumber)) {
reporter.logInvalidRoomNumber(roomNumber);
}
houseKeepingService.registerForCleaning(roomNumber);
minibarService.replenish(roomNumber);
// other operations ...
}
15. @DanielDeogun @danbjson #SecureByDesign #EDDD
Hardening your APIs
- Enforce Data Quality
Generic
Specific
public void checkout(final int roomNumber)
public void checkout(final RoomNumber roomNumber)
Enforce data quality
16. @DanielDeogun @danbjson #SecureByDesign #EDDD
Cluttered Entity
class Order {
private ArrayList<Object> items;
private boolean paid;
public void addItem(String isbn, int qty) {
if(this.paid == false) {
notNull(isbn);
inclusiveBetween(10, 10, isbn.length());
isTrue(isbn.matches("[0-9X]*"));
isTrue(isbn.matches("[0-9]{9}[0-9X]"));
Book book = bookCatalogue.findByISBN(isbn);
if (inventory.availableBooks(isbn) >= qty) {
items.add(new OrderLine(book, qty));
}
}
}
//Other logic...
}
17. @DanielDeogun @danbjson #SecureByDesign #EDDD
De-Cluttered Entity
class Order {
private ArrayList<Object> items;
private boolean paid;
public void addItem(ISBN isbn, Quantity qty) {
notNull(isbn);
notNull(qty);
if(this.paid == false) {
Book book = bookCatalogue.findByISBN(isbn);
if (inventory.availableBooks(isbn).greaterOrEqualTo(qty)) {
items.add(new OrderLine(book, qty));
}
}
}
//Other logic...
}
20. @DanielDeogun @danbjson #SecureByDesign #EDDD
But…
https://flic.kr/p/eGYhMw
https://creativecommons.org/licenses/by/2.0/
… what about performance?
https://flic.kr/p/2pvb2T
https://creativecommons.org/licenses/by/2.0/
… it becomes a lot of classes!
… isn’t it overly complex?
https://flic.kr/p/7Ro4HU
https://creativecommons.org/licenses/by/2.0/
21. @DanielDeogun @danbjson #SecureByDesign #EDDD
… Making it
Secure by Design
OWASP:
• Injection Flaw
• Cross-site scripting (XSS)
Seals lots of small holes
https://flic.kr/p/85qctm
https://creativecommons.org/licenses/by/2.0/
Confidentiality
Integrity
Availability
22. @DanielDeogun @danbjson #SecureByDesign #EDDD
Contains several
concepts from DDD
40% Discount code
ctweddd17
Design secure
software without
“thinking” about
security
There’s a Book…
Shameless plug…
23. @DanielDeogun @danbjson #SecureByDesign #EDDD
Key Take Aways
Domain Primitives
- are native to your domain
- form a conceptual whole
- easy way to improve and secure existing code