views:

103

answers:

2

I am planning the implementation of an Inheritance Mapper pattern for an application component http://martinfowler.com/eaaCatalog/inheritanceMappers.html

One feature it needs to have is for a domain object to reference a large list of aggreageted items (10,000 other domain objects)

So I need some kind of lazy loading collection to be passed out of the aggregate root domain object to other domain objects.

To keep my (php) model scripts organised i am storing them in two folders:

MyComponent\
 controllers\
 models\
  domain\     <- domain objects, DDD repository, DDD factory
  daccess\    <- PoEAA data mappers, SQL queries etc
 views\

But now I am racking my brains wondering where my lazy loading collection sits. It seems to stride both layers. Internally its a kind of data mapper, externally its a domain object.

Any suggestions / justifications for putting it in one place over another another?


  • daccess = data access
  • DDD = Domain Driven Design Patterns, Eric Evans - book
  • PoEAA = Patterns of Application Architecture Patterns, Martin Fowler - book
+1  A: 

Are you hand writing your data access layer? If so, you may want to try the technique outlined here:

http://mynerditorium.blogspot.com/2010/01/practical-pi-lazy-loading-for-your-hand.html

Note that I am following more of a standard DAO pattern, but I think you could apply the lazy loading bits to your specific pattern.

When using the above technique, I attach the lazy loading collection to the aggregate in the aggregate's DAL. However, I would consider the collection to be a member of the domain layer.

Daniel Auger
Thanks for that. Yes rolling my own for a legacy mess. Having followed your link I am now torn between: * http://ayende.com/Blog/archive/2006/05/12/25ReasonsNotToWriteYourOwnObjectRelationalMapper.aspxand * http://www.joelonsoftware.com/articles/fog0000000069.html
JW
You're torn between advice given in posts 4 years old and 10 years old respectively? Oy vey
George Mauer
Yep, I'd consider advice that's 4, 10 or even a thousand years old (Although I'm not particularly religious and would never take it as doctrine without a check on the alternatives)
JW
+2  A: 

The simple answer is that it probably sits in your DataAccess layer.

//Domain Object
class Store {
  public function GetGiantListOfProducts() { }
}

//DataAccess Object
class LazyLoadingStore extends Store {
  public function GetGiantListOfProducts() { // function override
     // data access code
  }
}

Then, your DAO might look like this:

class StoreProvider {
  public function GetStoreById($id) {
     //User expects a list of Store, but you actually return a list of LazyLoadingStore - nobody need know the difference
  }
}

The more complicated answer is - this reeks. Do you really need to lazy load stuff? It might be a better idea to re-examine your aggregate roots. Perhaps you don't need a $store.GetGiantListOfProducts() method at all and could gracefully sidestep the entire problem by changing the relationship traversal where each Product has a GetStore() method and you get a list of products like so:

class ProductProvider {
  public function GetAllForStore($store) {
     // return list of products for the store
  }
}

On the other hand, if the relationship has to exist the way that you initially sketched it out, then perhaps lazy loading is actually a concept that is meaningful to the domain? In this case it lives in the domain and should probably have a more specific and meaningful name than simply LazyLoader.

Makes sense?

George Mauer
Hi thanks for the answer. One thing, in your first example is LazyLoadingStore extending Store? Perhaps there is a typo there. Not sure. After some pondering, I think you were right in the second part of your answer in the sense that this is something that is more 'domain' than 'data access'.
JW
Yup, It was a typo. Good catch. I fixed it. Been forever since I programmed php so the syntax doesn't come easy.
George Mauer