Patterns of Enterprise Application Architecture (The Addison-Wesley Signature Series)
by Martin Fowler

Read more about this title…

This book is amazing, I could probably read it over and over again. The patterns that it presents makes a lot of sense, the actual implementations and examples could probably re-vamped but I’m finding that it’s a great starter to trying to understand the concepts.
So today I’m trying to grok this concept of the “IDENTITY MAP”. The book defines it as:
“Ensures that each object gets loaded only once by keeping every loaded object in a map. Looks up objects using the map when referring to them.”
I put together a quick implementation that I’m using for an assignment I’m writing for school. I’m creating repositories that have 2 dependencies. First dependency is a Data Mapper (not to be confused with a Mapper) and the second is an Identity Map.
As objects are requested from the repository, the repository is checking the identity map to see if an instance has been loaded, if it has it’s immediately returned to the caller. If the object is not in the map the repository leverages the data mapper to load the object, then adds it to the map and returns it to the caller.
The Data Mapper is defined as:

“A layer of Mappers that moves data between objects and a database while keeping them independent of each other and the mapper itself.” - PoEAA I created a Layer Supertype to register objects in the map. The Domain Layer Super type demands that domain objects had an ID. The ID is what’s getting used to load and register objects into the map.
The Layer Supertype is defined as:

“A type that acts as a the supertype for all types in it’s layer.” - PoEAA

The Domain Layer Super Type.

1 public interface IDomainObject {
2         long ID();
3     }

My actual implementation of the identity map looks like this…

 1 public class IdentityMap> T > : IIdentityMap> T > where T : IDomainObject {
 2         public IdentityMap() {
 3             _items = new List> T >( );
 4         }
 5 
 6         public void Add( T domainObject ) {
 7             EnsureObjectHasNotAlreadyBeenAdded( domainObject );
 8             _items.Add( domainObject );
 9         }
10 
11         public T FindObjectWithIdOf( long idOfObjectToFind ) {
12             foreach ( T item in _items ) {
13                 if ( item.ID( ).Equals( idOfObjectToFind ) ) {
14                     return item;
15                 }
16             }
17             return default( T );
18         }
19 
20         private void EnsureObjectHasNotAlreadyBeenAdded( T domainObject ) {
21             if ( ContainsObjectWithIdOf( domainObject.ID( ) ) ) {
22                 throw new ObjectAlreadyAddedToIdentityMapException( domainObject );
23             }
24         }
25 
26         private readonly IList> T > _items;
27     }

One of the benefits I like about the Identity Map is that it acts as an in memory cache for objects loaded from the database. This reduces the number of trips to and from the persistence store.

Source Code

comments powered by Disqus