Struggling with Child object concept in CSLA

Struggling with Child object concept in CSLA

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


RameshKandukuri posted on Monday, December 10, 2007

I have been evaluating and playing with CSLA from last one week. Please correct me if my observations are wrong.

Whether an object is child or parent(root) has to made at the design time (when  you write code for that object's class). Being a child or parent affects how that object is persisted in a database. A child's inert/update/delete logic HAS to be always called from within a parent - since we cannot call Save method inside a child. Is this right?

This means if  I need to just edit a single child object, the parent object has to be updated too. But a child object need not to be loaded from a full parent object instance. It can be, but not all the time. A ParentId is sometimes enough for a child object to stand on its own. It depends on the UI design (that particular use case). It is a UI behavior in my opinion. 

The framework need to allow even a child object to stand on its own. Can I have Static Factory methods on the child to call Delete/Update/Insert directly on the child object?

Thank you.

Q Johnson replied on Monday, December 10, 2007

Your struggle will be over when you let go of the idea that an entity in your problem domain is only modeled in your code in one way, one time.

An Invoice is a good example.  If you show the user a Customer (parent) with a list of available Invoices (children), you could allow them to select a single invoice and open it in a new screen/dialog for editing - as a an Editable Root Object (which will probably be a PARENT in this context with Line Item children, right?).

You model the items in your problem domain in the appropriate manner for the behavior you are modeling.  When the item is behaving as a child, it should be coded as a child.  When it is behaving as a parent, code it as a parent. 

It's all about the behavior.

Have fun with CSLA.

RameshKandukuri replied on Monday, December 10, 2007

Thank you "Q"  for the reply.

When the item is behaving as a child, it should be coded as a child.  When it is behaving as a parent, code it as a parent.  " I totally get this and hence lies my challenge. If my object has both Parent and Child behaviors do we then create 2 separate classes - Same Invoice class behaving as Child and also as a root. Or is there a way to represent both the behaviors in one class?

 

Thank you.

Q Johnson replied on Tuesday, December 11, 2007

RameshKandukuri:

If my object has both Parent and Child behaviors do we then create 2 separate classes - Same Invoice class behaving as Child and also as a root. Or is there a way to represent both the behaviors in one class?

You are going to have a hard time letting go of the "my object" idea - as we all did at some point.  But you don't have a single object here.  Objects should be defined by their behaviors and you have potentially several here.

So YES, create them as separate classes because they have separate behavior.  [After you have worked with the framework for a while, you can consider whether you want to experiment with the "switchable" object.  But frankly, that over-simplifies the behaviors in my opinion.  It seems to presuppose that the object behaves only one way as a root object and only one way as a child object.] 

The Invoice we used in the earlier example certainly could behave very differently in different child scenarios.  When it's a child of customer, it may only need to offer properties for identification and description.  [Presumably if the user makes a selection of the object based on that information, they will get a UI element (form, dialog, user control, whatever) that exposes the Invoice as a root object with much richer properties for which the user has chosen it.]

But that Invoice might also be one in a collection of many Invoices being processed for printing, or against which aging is being performed for the calculation of late payment charges. 

The view taken by nearly everyone here is that these are fundamentally different behaviors and should be coded in different classes.  Many here subscribe to the "one responsibility per class" design paradigm.  Others are not quite so strict.  But almost no one here would consider implementing the behaviors mentioned here in a single class.  And they reap big benefits in terms of clarity and ease of maintenance for doing so.

It will probably help you to try and think of NAMES that make sense in describing the behaviors for classes.  That way you aren't confused by referring to them mentally as "Invoice" all the time.  In fact, it would probably be best to NEVER call them just "Invoice." You may like CustomerInvoice (a child), InvoiceHeader (root object), PaperInvoice (another child), and AgeInvoice (yet another child), for example.  But whatever choices you make, be sure they help keep your focus on modeling behavior.

If you are rolling your eyes thinking of the huge amount of code you have to write for all these classes, I have two assurances for you.  First, the classes are going to be much smaller.  After all, you will be exposing only the properties and methods needed for the limited functionality of their single (or at least limited) responisibility.  Second, before long you are probably going to join the large number of folks here that use code generation tools that will basically eliminate your concern about volumes of code-writing time.  They won't design your objects or code every line for you.  But they take all the grunt work out of the considerable task of private data, public properties, and CRUD methods.  You'll only have to actively focus on the behavior that's unique to each particular class.  But get a project or two done by hand before you tackle another technology and its learning curve. 

Good luck with CSLA!   

tna55 replied on Monday, December 10, 2007

Hi,

I am new here as well so do not consider my suggestions are not really concrete and more experienced people might have othe remarks.

I think that if you have some object that can be independently saved/deleted then that is not a child object. It may be a child 'record in database' but that does not mean it is a child 'object'.

For example Sale and SaleLineItem are parent child because SaleLineItem cannot be edited independently. Editing or deleting SaleLineItem would mean that you are basically editing the Sale as a whole.

May be if you can give us an example of what parent and child objects you have and the use-case then it would be easier to see where you are coming from.

Tahir

Plowking replied on Monday, December 10, 2007

You can make a switchable root/child object, but often it is bad design to do so. i.e. you are doing it to try and achieve reuse.

The framework doesn't limit you to handling parent child relationships in any particular way, you can decide how to control it if you wish or use the markAsChild concept described in the books. When it comes to data access the framework gives you the dataportal methods which are cool if you want a remote data portal and are generally good to use anyway from a consistancy in design viewpoint.

CSLA doesn't limit OO programming in anyway, it merely gives you an enriched framework offering functionality that is lacking in the .NET framework (i.e. the .NET framework is not perfect for making business object based applications "Out of the box")

Ian

ayubu replied on Monday, December 10, 2007

From the UI perspective it makes sense to access the object via its parent and CSLA encourages that.

In your case you can make your class "switchable" so in some circumstances it can be retrieved on itself while in others it can be accessed via the parent.

Copyright (c) Marimer LLC