org.fuin.dsl.ddd - a domain-driven design (ddd) dsl

14
org.fuin.dsl.ddd - A Domain-Driven Design (DDD) DSL Domain-Specific Language (DSL) Expressing a Domain-Driven Design (DDD) model Model can be used for any type of „model to text“ (code generation) or „model to model“ transformation Xtext based Eclipse Plugin Syntax Coloring Content Assist Validation and Quick Fixes Open Source https://github.com/fuinorg/org.fuin.dsl.ddd LGPL License

Upload: michael-schnell

Post on 08-Jul-2015

193 views

Category:

Software


0 download

DESCRIPTION

Describes a DSL that is available as Eclipse Plugin at https://github.com/fuinorg/org.fuin.dsl.ddd

TRANSCRIPT

Page 1: org.fuin.dsl.ddd  -  A Domain-Driven Design (DDD) DSL

org.fuin.dsl.ddd - A Domain-Driven Design (DDD) DSL

Domain-Specific Language (DSL)

Expressing a Domain-Driven Design (DDD) model

Model can be used for any type of „model to text“ (code generation) or

„model to model“ transformation

Xtext based Eclipse Plugin

Syntax Coloring Content Assist Validation and Quick Fixes

Open Source

https://github.com/fuinorg/org.fuin.dsl.ddd LGPL License

Page 2: org.fuin.dsl.ddd  -  A Domain-Driven Design (DDD) DSL

org.fuin.dsl.ddd – Basic concepts (Context / Namespace / Type)

context sales {

namespace b.c.d {

type String

type Integer

}

}

File Extension: *.ddd Can contain multiple contexts Filename is completely independent

from content

Context

DDD Term = Bounded Context

Namespace

DDD Term = Module Also known as „Package“ Names separated by a dot

Type

External Type Defined outside the DSL

Page 3: org.fuin.dsl.ddd  -  A Domain-Driven Design (DDD) DSL

org.fuin.dsl.ddd – Basic concepts (Import / Constraint)

Import Required when using types from other

namespaces

Constraint

Condition that must be satisfied Also known as „Business Rule“ Has a name unique in the namespace Always is related to a type it restricts

(„on“) – Internal or external type Has zero or more variables used to

customize the condition Defines an error message

All variables from the constraint canbe used

The validated value itself is a predefined variable („vv“)

context x {

namespace constr {

import types.*

/** Makes sure a string has exactly a given size. */

constraint ExactLength on String {

/** Expected length. */

Integer expected

message "Expected an exact length of ${expected},

but value was: '${vv}'"

}

}

}

Page 4: org.fuin.dsl.ddd  -  A Domain-Driven Design (DDD) DSL

org.fuin.dsl.ddd – Variables: Basics

Variable

May have a comment (Optional)

Has a type (internal/external) and a name

Is by definition not nullable, except it startswith the nullable keyword

Inherits meta data (slabel, label, …) andcomment from internal types

Can overwrite the meta data

May define invariants (References one ormore constraints)

/** Comment for never-null “a”. */

String a

/** Comment for nullable “b”. */

nullable String b

// Inherits the comment + meta data

CustomerName name

/** Overwrites the CustomerName’s comment. */

nullable CustomerName name2 {

// Overwrites the CustomerName’s short label

slabel “CNA“

}

String name3 invariants Length(1, 50)

Page 5: org.fuin.dsl.ddd  -  A Domain-Driven Design (DDD) DSL

org.fuin.dsl.ddd – Variables: Meta Data

Meta data

slabel = Short label used when space in theUI is limited (Example: Table headers)

label = Label for the UI

tooltip = Tooltipp for the UI

prompt = Prompt text (like „ Enter searchkeywords…“ for input fields)

examples = Values that may be used in mockups, tests, … (Separated by a space)

String createdBy {

slabel "Created"

label "Created by user"

tooltip "Name of the user that created the record"

prompt "<Enter>"

examples "pparker mjwatson hosborn“

}

Page 6: org.fuin.dsl.ddd  -  A Domain-Driven Design (DDD) DSL

org.fuin.dsl.ddd – Value Objects

Value Object

May have a comment (Optional)

Has a name that is unique in the namspace

Can be based on an external type (Optional)

Define optional meta data (slabel, label, …)

Defines zero or more variables

May define constructors and methods

/** Lanugage specific name. */

value-object ContentName base String {

slabel "CN"

label "Content name"

tooltip "Unique name of the content"

/** Human readable name. */

String name invariants Length(1, 50)

/** Language the name is in. */

Locale locale

}

Page 7: org.fuin.dsl.ddd  -  A Domain-Driven Design (DDD) DSL

org.fuin.dsl.ddd – Aggregate ID / Entity ID

Aggregate ID

Is a special form of value object

Identifies an aggregate

Same rules as for value objects

Entity ID

Is a special form of value object

Identifies an entity

Same rules as for value objects

/** Identifies an Xyz aggregate uniquely in the context. */

aggregate-id XyzId identifies Xyz base UUID {

UUID val

}

/**

* Identifies an Abc entity uniquely in the context

* of it’s aggregate.

*/

entity-id AbcId identifies Abc base Integer {

Integer val

}

Page 8: org.fuin.dsl.ddd  -  A Domain-Driven Design (DDD) DSL

org.fuin.dsl.ddd – Enums

Enum

Is a special form of value object

Enumeration of values

Defines a fix set of instances

Same rules as for value objects

enum Cards {

String name

instances {

CLUB

SPADE

HEART

DIAMOND

}

}

Page 9: org.fuin.dsl.ddd  -  A Domain-Driven Design (DDD) DSL

org.fuin.dsl.ddd – Aggregates: Overview

Aggregate

Has a name that should be unique in thecontext

Has an aggregate identifier

Defines a number of variables (Externaltypes, value objects, services or entitiesbelonging to this aggregate)

Defines one or more constructors andmethods

References to other aggregates are onlyallowed using aggregate identifier

/**

* A customer (sometimes known as a client, buyer,

* or purchaser) is the recipient of a good, service

* or product.

*/

aggregate Customer identifier CustomerId {

CustomerName name

:

constructor createWithA { … }

constructor createWithB { … }

method doSomething { … }

method whatever { … }

}

Page 10: org.fuin.dsl.ddd  -  A Domain-Driven Design (DDD) DSL

org.fuin.dsl.ddd – Aggregates/Entities: Constructors & Methods

Constructor / Method

Defines zero or more parameters

Can have constraints

May fires one or more events

Method

May return a result:

returns XyzType

constructor create {

CustomerName newName

:

constraints {

AbcConstraint, DefConstraint, …

}

event CustomerCreatedEvent { … }

event InformTheAdminEvent { … }

:

}

Page 11: org.fuin.dsl.ddd  -  A Domain-Driven Design (DDD) DSL

org.fuin.dsl.ddd – Aggregates/Entities: Events

Events

Defines zero or more variables

Defines a message All variables from the event can be

used in the message

Is the result of a successfulconstructor/method execution

It‘s a good style to include all informationthat is available and may be of interest forevent consumers

/**

* The name of a customer was changed.

*/

event CustomerNameChangedEvent {

CustomerId id // Inherits doc from CustomerId

/** Old name before the change. */

CustomerName oldName

/** New (current) name. */

CustomerName newName

message "Changed the name of customer ${id} from

'${oldName}' to '${newName}'"

}

Page 12: org.fuin.dsl.ddd  -  A Domain-Driven Design (DDD) DSL

org.fuin.dsl.ddd – Aggregates/Entities: Method References

A method of an aggregate or entity mayreference a method of a direct sub-entity (ref)

Referencing is just a shortcut to avoidenumerating the same parameters again

One can think of this as adding all the variables of the referenced method to the ones defineddirectly in the referencing method

aggregate Customer identifier CustomerId {

method changePersonName ref Person.changeName {

constraints {

PersonExistsConstraint

}

}

}

entity Person identifier PersonId root Customer {

method changeName {

PersonName name

}

}

Page 13: org.fuin.dsl.ddd  -  A Domain-Driven Design (DDD) DSL

org.fuin.dsl.ddd – Entity

Entity

Has a name that should be unique in thecontext

Has an entity identifier

References the aggregate root it belongs to

Same functionality as an aggregate

/**

* Contact person for a customer.

*/

entity Person identifier PersonId root Customer {

PersonName name

:

}

Page 14: org.fuin.dsl.ddd  -  A Domain-Driven Design (DDD) DSL

org.fuin.dsl.ddd – Service

Service

Has one or more methods

May define a return value (Optional)

Can have constraints

May be referenced from aggregates orentities

Parameters/Return Type in a service cannotreference aggregates/entities directly –Only by their IDs.

/** My service documentation. */

service MyService {

/**

* Loads the display name of a customer.

*/

method loadPersonName {

PersonId id

returns PersonName

constraints { PersonExistsConstraint }

}

}