Granularity and Csla Object(s)

Granularity and Csla Object(s)

Old forum URL: forums.lhotka.net/forums/t/5670.aspx


decius posted on Friday, October 24, 2008

I am hoping to get the community's general concensus on the topic of structuring a series of objects for both fine-granular and coarse-granular situations.

Here's the situation of my work environment:

Seldomly, it is needed to fetch a whole bunch of objects at once.  So I figure I'd make a EditableRoot with several children.  But sometimes these children need to be fetched by themselves.  What's the typical approach for this kind of situation?

I've considered a couple options:

  1. Give the children of the parent object public factory methods that can call up the dataportal on their own.  Thus, this would make them pseudo Child/Root objects... ? However, I feel like that might be unintuitive to the UI developers if a object is both a child AND a root...
  2. Create fresh new "Root" versions of the child objects.  But this seems like it would add too much extra code/objects to maintain.

The end result I'm trying to achieve is is finding the best way setup a series of objects that optimize granularity and flexibility. I was hoping to hear about other's opinions and wisdom on this topic.

dnwheeler replied on Friday, October 24, 2008

I do something like this in one situation (I have a business object of type X that holds a list of child objects also of type X). I simply put two Get() methods on the object, one for client use, and one for server use. The client version then calls DataPortal.Fetch() and the other calls DataPortal.ChildFetch(). There are corresponding DataPortal_Fetch and a Child_Fetch methods to handle the data access.

--Doug

rsbaker0 replied on Friday, October 24, 2008

Our application is (at least currently) implemented exactly this way. We just moved to CSLA 3.5 so I haven't started using the child data portal, but all of our objects could be arbitrarily composed. A root object would typically lazy load children, but if you need to fetch a child directly you can.

I think this would be tough to do if you are deriving your BO's directly from BusinessBase<T> and BusinessListBase<T> etc., but we have inserted a class in between that our BO's derive from that provides the necessary infrastructure support to make this fairly easy to do.

BusinessListBase<T>, in particular, wants child objects to be explicitly marked as such, but that can be handled in your factory Get methods.

Since IEditableBusinessObject has support for parents, it seems to me like all CSLA objects can either be children or not simply based on whether you have assigned a parent to them and marked them as children, but I admittedly have only worked with the framework for a little over a year and may not fully understand what trouble that might get you into.

dnwheeler replied on Friday, October 24, 2008

The ChildDataPortal automatically marks the object you are getting as a child (i.e. it calls MarkAsChild() on the target object in the Fetch() call (called from the static FetchChild() method), so there's no problem using a BusinessBase<T> derived objects.

--Doug

rsbaker0:

Our application is (at least currently) implemented exactly this way. We just moved to CSLA 3.5 so I haven't started using the child data portal, but all of our objects could be arbitrarily composed. A root object would typically lazy load children, but if you need to fetch a child directly you can.

I think this would be tough to do if you are deriving your BO's directly from BusinessBase<T> and BusinessListBase<T> etc., but we have inserted a class in between that our BO's derive from that provides the necessary infrastructure support to make this fairly easy to do.

BusinessListBase<T>, in particular, wants child objects to be explicitly marked as such, but that can be handled in your factory Get methods.

Since IEditableBusinessObject has support for parents, it seems to me like all CSLA objects can either be children or not simply based on whether you have assigned a parent to them and marked them as children, but I admittedly have only worked with the framework for a little over a year and may not fully understand what trouble that might get you into.

decius replied on Friday, October 24, 2008

Thanks for the input, this is definitely helping.  Sounds like you guys are confirming that it's acceptable to have a object act as both a child and root based on the factory method that's called, which was what I was wondering. 

I was unaware of the ChildDataPortal method in 3.5, I'm working with 3.0 currently, but it's cool to know about.  I don't really mind having to call MarkAsChild() manually in the factory method anyway. 

rsbaker0 replied on Saturday, October 25, 2008

As an aside, I get the definite impression from my experience on this forum that even though you *can* do this, there are good arguments that you shouldn't. Purists here say you should design an object for the specific use case it is needed for, and reuse it only if it's being used in *exactly* the same way.

Root objects and child objects are typically used in different ways, so you may end up with more complicated objects that have "If I'm a root do X else do Y". So, you end up with a single more weighty object instead of 2 simple,  straightforward, unambiguous objects.

I come from years of C++ development, so my tendency -- very hard to shed unfortunately -- is to reuse code through inheritance and other means whenever possible. Over the long term maintaining one application, though, you can end up with a large, unwieldy, and difficult to maintain source code base. A seemingly innocuous change can break a totally unrelated part of the application. So, I'm warming up to the "separate objects" viewpoint. Code generation, snippet type tools, and modeling tools make this much less onerous than it would have been 10 years ago.

decius replied on Saturday, October 25, 2008

Thanks for more great advice.  I was concered about this too.  Not only would it make the object less intuitive, but your right, you'd probably end up with a lot of extra conditional logic to indicate the object's state (root or child), making things more convoluted.  This purist philosophy makes a lot of sense, and definitely will help me make an educated decision.

Copyright (c) Marimer LLC