NoSQL Zone is brought to you in partnership with:

Bradley Holt is a web developer, entrepreneur, community facilitator, speaker, and an author. He is the co-founder of Found Line, a creative studio with capabilities in web development, web design, and print design. He is a Board Member at Vermont Community Access Media, a non-profit community media and technology center. He is a minor contributor of source code and bug reports to Zend Framework and an active member of the PHP community. He organizes the Burlington, Vermont PHP Users Group where he is a regular speaker and is involved with helping to organize other technology community events such as Vermont Code Camp. He has spoken at (or will be speaking at) SXSW Interactive, OSCON, OSCON Data, the jQuery Conference, and ZendCon. He is the author of Writing and Querying MapReduce Views in CouchDB and Scaling CouchDB, both published by O’Reilly Media. He blogs at bradley-holt.com and can be found on Twitter as @BradleyHolt. Bradley is a DZone MVB and is not an employee of DZone and has posted 17 posts at DZone. You can read more from them at their website. View Full User Profile

CouchDB is a Great Fit for Domain Driven Design

02.16.2012
| 2108 views |
  • submit to reddit

I’ve found CouchDB to be a great fit for domain-driven design (DDD). Specifically, CouchDB fits very well with the building block patterns and practices found within DDD. Two of these building blocks include Entities and Value Objects. Entities are objects defined by a thread of continuity and identity. A Value Object “is an object that describes some characteristic or attribute but carries no concept of identity.” Value objects should be treated as immutable.

Aggregates are groupings of associated Entities and Value Objects. Within an Aggregate, one member is designated as the Aggregate Root. External references are limited to only the Aggregate Root. Aggregates should follow transaction, distribution, and concurrency boundaries. Guess what else is defined by transaction, distribution, and concurrency boundaries? That’s right, JSON documents in CouchDB.

Let’s take a look at an example Aggregate, that representing a blog entry and related metadata. Note that the following UML diagrams are for classes in PHP, but it should be easy enough to translate these examples to any object-oriented programming language. We’ll start with the Entry Entity, which will serve as our Aggregate Root:

-----------------------------------------
|                 Entry                 
-----------------------------------------
|+ id : string                          
|+ rev : string                          
|+ title : Text                          
|+ updated : Date                        
|+ authors : Person[*]                  
|+ content : Text                        
-----------------------------------------
|+ __construct(entry : array) : void     
|+ toArray() : array                     
-----------------------------------------


The Text Value Object:

----------------------------------------------
|                    Text                    
----------------------------------------------
|- type : string                             
|- text : string                             
----------------------------------------------
|+ __construct(type : string, text : string) 
|+ toArray() : array                         
----------------------------------------------


The Date Value Object:

--------------------------------------
|                Date                
--------------------------------------
|- timestamp : integer               
--------------------------------------
|+ __construct(timestamp : integer)  
|+ __toString() : string             
--------------------------------------


The Person Value Object:

-------------------------------------------------------------
|                           Person                          
-------------------------------------------------------------
|- name : string                                            
|- uri : string                                             
|- email : string                                           
-------------------------------------------------------------
|+ __construct(name : string, uri : string, email : string) 
|+ toArray() : array                                        
-------------------------------------------------------------


I recommend serializing each Aggregate, starting with the Aggregate Root, into a JSON document. Control access to Aggregate Roots through a Repository. The toArray() methods above return an associative array representation of each object. The Repository can then transform the array into JSON for storage in CouchDB. Let’s take a look at the EntryRepository:

---------------------------------
|        EntryRepository        
---------------------------------
|                               
---------------------------------
|+ get(id : string) : Entry     
|+ post(entry : Entry) : void   
|+ put(entry : Entry) : void    
|+ delete(entry : Entry) : void 
---------------------------------


Here’s an example of what the Aggregate’s object graph might look like, serialized as a JSON document:

{
    "_id": "http://bradley-holt.com/?p=1251",
    "title": {
        "type": "text",
        "text": "CouchDB and Domain-Driven Design"
    },
    "updated": "2011-08-02T15:30:00+00:00",
    "authors": [
        {
             "name": "Bradley Holt",
             "uri": "http://bradley-holt.com/",
             "email": "bradley.holt@foundline.com"
        }
    ],
    "content": {
        "type": "html",
        "text": "<p>I've found CouchDB to be a great fit for…</p>"
    }
}

 
You can also provide access to CouchDB views through Repositories. In the above example, this could be through the addition of an index(skip : integer, limit : integer) : Entry[*] method to the the EntryRepository (note that this is a naive pagination implementation, especially on large data sets—but that’s beyond the scope of this blog post). For more complex views, you may want to create a separate Repository for each CouchDB view.

Source: http://bradley-holt.com/2011/08/couchdb-and-domain-driven-design/

Published at DZone with permission of Bradley Holt, author and DZone MVB.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)