framework for Domain-Driven Design in JavaScript (or CoffeeScript, recommended.)
$ npm install -g base-domain
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
- Base
- Facade
- BaseModel
- BaseFactory
- BaseRepository
- BaseService
- Entity
- AggregateRoot
- ValueObject
- BaseList
- BaseDict
- Base is an origin of all classes
- Base has Facade
- Base does not have any other properties or methods
- 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 is a base class of model
- essential methods for model are defined
- BaseModel is a child of Base
- BaseFactory is a base class of factory
- BaseFactory creates specific BaseModel instance
- BaseFactory is a child of Base
- 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 is child of BaseModel
- instance of ValueObject does not have id
- ValueObject.isEntity is false
- that's all of ValueObject
- Entity is child of BaseModel
- instance of Entity has id
- Entity.isEntity is true
- AggregateRoot is child of Entity
- AggregateRoot implements RootInterface, thus it can create other models, factories and repositories.
- BaseList is child of ValueObject
- BaseList has many BaseModels as items
- BaseList#items is array of specific BaseModel
- 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
model is classified into "Entity" and "ValueObject"
Entity is model with id, ValueObject is model without id.
# {domain-dir}/hospital.coffee
class Hospital extends require('base-domain').Entity
# property types
@properties:
name : @TYPES.STRING
address : @TYPES.STRING
beds : @TYPES.NUMBER
registeredAt : @TYPES.DATE
isValidated : @TYPES.BOOLEAN
doctors : @TYPES.MODEL 'doctor-list'
flags : @TYPES.MODEL 'flag-dict'
state : @TYPES.ENUM ['PREPARED', 'RUNNING', 'CLOSED']
module.exports = Hospital
@TYPES.XXX is an object and also a function.
@properties:
aaa: @TYPES.STRING
bbb: @TYPES.NUMBER 3
ccc: @TYPES.MODEL '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.
# {domain-dir}/hospital-factory.coffee
class HospitalFactory extends require('base-domain').BaseFactory
@modelName: 'hospital'
module.exports = HospitalFactory
# {domain-dir}/hospital-repository.coffee
class HospitalRepository extends require('base-domain').BaseRepository
@modelName: 'hospital'
module.exports = HospitalRepository
domain = require('base-domain').createInstance
dirname: '/path/to/domain-dir'
Hospital = domain.getModel('hospital')
hospitalFactory = domain.createFactory('hospital')
hospitalRepository = domain.createRepository('hospital')
hosp = hospitalFactory.createFromObject(name: 'Suzuki Clinic')
hospitalRepository.query(where: name: 'CureApp Hp.').then (hospitals)->
console.log hospitals
# {domain-dir}/hospital-list.coffee
class HospitalList extends require('base-domain').BaseList
@itemModelName: 'hospital'
module.exports = HospitalList
# {domain-dir}/hospital-dict.coffee
class HospitalDict extends require('base-domain').BaseDict
@itemModelName: 'hospital'
@key: (item) -> item.id
module.exports = HospitalDict