base-domain
framework for Domain-Driven Design in JavaScript (or CoffeeScript, recommended.)
installation
$ npm install -g base-domain
concept
base-domain helps easier practice of Domain-Driven Design.
- list models in the domain of your concern (by your own way)
- define models with base-domain
- define their factories with base-domain
- define their repositories with base-domain
- define services with base-domain if needed
essential classes and relations
- Base
- Facade
- BaseModel
- BaseFactory
- BaseRepository
- BaseService
- Entity
- AggregateRoot
- ValueObject
- BaseList
- BaseDict
Base
- Base is an origin of all classes
- Base has Facade
- Base does not have any other properties or methods
Facade
- Facade is the gate of all classes
- Facade knows all classes
- Facade is module-exported in base-domain: require('base-domain') returns Facade class
BaseModel
- BaseModel is a base class of model
- essential methods for model are defined
- BaseModel is a child of Base
BaseFactory
- BaseFactory is a base class of factory
- BaseFactory creates specific BaseModel instance
- BaseFactory is a child of Base
BaseRepository
- BaseRepository is a base class of repository
- BaseRepository connects to database, filesystem or other external data resources (settings needed).
- BaseRepository saves specific BaseModel to data resources
- BaseRepository read BaseModels from data resources
- BaseRepository has BaseFactory (to generate BaseModel from data resources)
ValueObject
- ValueObject is child of BaseModel
- instance of ValueObject does not have id
- ValueObject.isEntity is false
- that's all of ValueObject
Entity
- Entity is child of BaseModel
- instance of Entity has id
- Entity.isEntity is true
AggregateRoot
- AggregateRoot is child of Entity
- AggregateRoot implements RootInterface, thus it can create other models, factories and repositories.
BaseList
- BaseList is child of ValueObject
- BaseList has many BaseModels as items
- BaseList#items is array of specific BaseModel
BaseDict
- BaseDict is child of ValueObject
- BaseDict has many BaseModels as items
- BaseDict#items is dictionary of key => specific BaseModel
- BaseDict.key is function to get key from item
usage
model definition
model is classified into "Entity" and "ValueObject"
Entity is model with id, ValueObject is model without id.
# {domain-dir}/hospital.coffee 'base-domain'Entity # property types @properties: name : @TYPESSTRING address : @TYPESSTRING beds : @TYPESNUMBER registeredAt : @TYPESDATE isValidated : @TYPESBOOLEAN doctors : @TYPESMODEL 'doctor-list' flags : @TYPESMODEL 'flag-dict' state : @TYPESENUM 'PREPARED''RUNNING''CLOSED' module.exports = Hospital
properties definition
@TYPES.XXX is an object and also a function.
@properties: aaa: @TYPESSTRING bbb: @TYPESNUMBER 3 ccc: @TYPESMODEL 'foo-bar'
mark | property type | meaning | arg1 | arg2 |
---|---|---|---|---|
x | @TYPES.ANY | prop accepts any type | default value | |
x | @TYPES.STRING | prop is string | default value | |
x | @TYPES.NUMBER | prop is number | default value | |
x | @TYPES.DATE | prop is date | default value | |
x | @TYPES.BOOLEAN | prop is boolean | default value | |
x | @TYPES.ARRAY | prop is array | default value | |
x | @TYPES.OBJECT | prop is object | default value | |
x | @TYPES.BUFFER | prop is buffer | default value | |
x | @TYPES.GEOPOINT | prop is geopoint | default value | |
o | @TYPES.CREATED_AT | date set when first saved | default value | |
o | @TYPES.UPDATED_AT | date set each time saved | default value | |
o | @TYPES.MODEL | prop is BaseModel | model name | id prop name (if model is Entity) |
o | @TYPES.ENUM | prop is index of the alternatives | alternatives | default value |
Types with marked "x" just provide the name of the type. base-domain does not validate the prop's type.
factory definition
# {domain-dir}/hospital-factory.coffee 'base-domain'BaseFactory @modelName: 'hospital' module.exports = HospitalFactory
repository definition
# {domain-dir}/hospital-repository.coffee 'base-domain'BaseRepository @modelName: 'hospital' module.exports = HospitalRepository
use them by facade
domain = require'base-domain'createInstance dirname: '/path/to/domain-dir' Hospital = domaingetModel'hospital'hospitalFactory = domaincreateFactory'hospital'hospitalRepository = domaincreateRepository'hospital' hosp = hospitalFactorycreateFromObjectname: 'Suzuki Clinic' hospitalRepositoryquerywhere: name: 'CureApp Hp.'then consolelog hospitals
list definition
# {domain-dir}/hospital-list.coffee 'base-domain'BaseList @itemModelName: 'hospital' module.exports = HospitalList
dict definition
# {domain-dir}/hospital-dict.coffee 'base-domain'BaseDict @itemModelName: 'hospital' : itemid module.exports = HospitalDict