Why have child objects? Why not all roots?

Why have child objects? Why not all roots?

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


Cary Mcanally posted on Tuesday, February 03, 2009

I have searched this forum over and over and still can not find an answer.

I see where roots and childs are described here and in the book but never is it explained WHY have them at all.  Why mark an object as child?  Why not just use a root objects?

They have the same basic structure.  Child objects have an internal constructors to be used by a parent, but so can a root.

Is there a performance problem with calling Save on child objects and going through the portal?  Is that why child object has to use internal non portal Data Access methods?

I see where you can have a Swithable object but it seems like a level of complexity for little gain.  I do not see the justification for marking an object as child and changing it's behavior.

So far I see where the BLB is the only object requiring an object to be marked as a child.  Specifically in the REMOVE. WHY?

My question stems from implementing an workflow solution that needs to work with an object as both a Root and Child.

Thanks in advance.

ajj3085 replied on Tuesday, February 03, 2009

Child objects are used when changing and updating them outside of their intended context doesn't make sense.  Take an order for example.  Does it make any sense at all to work with a single LineItem WITHOUT having the other line items or information about the order available?  Probably not... especially considering that a line item may have a rule that it can be the only instance in an order (for example, a PackingFeeLineItem that must appear at most once in the entire order).

Cary Mcanally replied on Tuesday, February 03, 2009

This does not answer the question WHY CSLA requires objects to be marked as a child in collections. 

Because BLB are requiring their items to be Child objects this is forcing me to use Switchable objects.  I am looking for an explaination of why the BLB requires this.  It looks like they could easily not require their items to be child object and CSLA would work fine.  What other behaviors are affected.

Repling to the  example in the previous post: 

In a workflow use case you may have users that only verify if they have the quantity on hand listed on an Order Item..   They do not need to load the order object they just work the order item objects.  As I currently understand CSLA to implement your example in my environment you have to do one of two things. Create a switchable object or create two objects0 (one as child and  as root) and duplicate the business logic between the two.  Also you can not rely on the Order enforcing you have only one Order Item.  The rule has to be in the Order Item to not save if it finds an existing item in the data store.  Otherwise you could get two users entering bad data using two order objects.  This example and logic does not require the item to be a child.

 

ajj3085 replied on Tuesday, February 03, 2009

Well one reason is to prevent Save from being called directly on the child.  FWIW, nothing is forcing you to use switchable object, and in most cases the need to create switchables indicated a bad design.  You're trying to re-use the same class in two use cases where the behavior is different.

The rest of your post sounds like you're talking about locking issues and concurrency.  If two users can edit the same order you'll need to detect if the the order has changed and take action.  In my case, I tell the user that someone else has already modified the order and they will have to re-open the order and redo their changes.

RockfordLhotka replied on Tuesday, February 03, 2009

Cary Mcanally:

This does not answer the question WHY CSLA requires objects to be marked as a child in collections. 



That isn't an accurate statement. CSLA certainly allows you to create all root objects.

In stateless scenarios, like a stateless web app, this is sometimes the preferred solution.

The drawback to doing this has nothing to do with CSLA, and everything to do with OO design. It comes down to a simple matter of cost vs benefit.

If you design objects to work together to solve a business problem, you can often embed business rules into the very relationships between objects. The fact that orders have line items, and line items always belong to an order becomes a natural extension of the business model itself. No explicit coding is required to enforce this relationship.

If all objects are "root" objects, and you don't use any concept of containment or aggregation, then you must explicitly write code to enforce those rules that would have been implicit.

In short, you have to write and debug more code.

So it is more expensive to have all root objects, because you give up a lot of the benefit of OO design and programming.

On the other hand, if you need super-scaling in a web site, you'll pay that cost because (regardless of CSLA or not) this is what you must do to get that level of scalability.

Your example of workflow is, I think, a little different.

A workflow orchestrates a sequences of activities. Each activity is a black box with clearly defined inputs and outputs (or at least that's how they should be viewed). In other words, an activity is very much like a FORTRAN or Pascal procedure.

That's the view from the outside. The view from the inside of the activity is different. Inside an activity, you get clearly defined inputs, and you must provide clearly defined outputs. And you must perform a (hopefully) clearly defined task.

That's the definition of a use case. In other words, an activity is an almost academic example of an OO use case. Which means that you can implement your activity (internally) using OO concepts.

If you search the forum's history, you'll find that I consistently say that objects should be defined and designed on a per-use case basis. This is true for activities too. You should define and design your objects to meet the needs of the activity.

For many simpler activities, this really might mean that you have just one root object that performs the required task.

For more complex activities you might have more complex object models - all root, or objects with children. It really depends on the use case and how the object model falls out to meet that use case.

Cary Mcanally replied on Friday, February 06, 2009

I am missing something somewhere.  I am trying to use only root objects but I do not see where CLSA alows it.

The Delete methods on the BusinessBase are throwing execeptions when removing objects from a BusinessListBase object. 

Is there a switch to change this in CSLA and if no how do you bypass the exceptions CLSA throws?

I do not want to modify CSLA but so far I can see any other way around the exceptions.  Any help would very appreciated.

 

 

 

ajj3085 replied on Friday, February 06, 2009

A BO in a collection is, by definition, a child.  It's directly contained in another BO. 

If you're using WinForms or maybe even WPF, you can have the collection subclasss EditableRootListBase.

If you're using asp.net, you'll need to get rid of the collection completely.  It may also be that you're using an editable collection where you want a readonly collection, and each child in the collection has a GetEditObject method which loads the root editable object.

Cary Mcanally replied on Friday, February 06, 2009

I have an EditableRootListBase.  The problem come in when you try to use the Remove on the collection.  The BusinessBase throws and exception that the BusinessBase must be a child or you have to call the delete on the object.

If this is true then do you loose the ablilty to mark objects in the collection as deleted?  Basically you no longer have UNDO functionality on the collections.

RockfordLhotka replied on Friday, February 06, 2009

Your base class for your collection is almost certainly BusinessListBase. You need it to be EditableRootListBase.

 

BLB contains child objects. End of story.

 

ERLB contains root objects. If you want a collection of root objects, this is one way to get that.

 

However, you must understand that ERLB is designed specifically to support in-place grid editing scenarios in Windows Forms, WPF and Silverlight. Using it outside that scenario may or may not meet your needs.

 

Be aware that changes to an ERLB occur immediately. Remove an item, and that item goes and deletes itself right now from the database. No undo. No going back.

 

Also be aware that outside a rich client grid binding scenario you must manually call SaveItem() to save changes to an object in the collection. In a rich client scenario this occurs automatically due to data binding, but in the web you must do this manually because Web Forms data binding has no concept along these lines.

 

Rocky

 

 

From: Cary Mcanally [mailto:cslanet@lhotka.net]
Sent: Friday, February 06, 2009 10:20 AM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] Why have child objects? Why not all roots?

 

I have an EditableRootListBase.  The problem come in when you try to use the Remove on the collection.  The BusinessBase throws and exception that the BusinessBase must be a child or you have to call the delete on the object.

If this is true then do you loose the ablilty to mark objects in the collection as deleted?  Basically you no longer have UNDO functionality on the collections.



Cary Mcanally replied on Friday, February 06, 2009

I am binding to an in-place editing grid.

I can deal with not having UNDO in the ERLB. 

I think I setup my ERLB up just like the it says in pg 188 of the 2008 book and my REMOVE is throwing errors that the object must be a child.

Is there something else I have to do to change the behavior or is the REMOVE method not valid in an ERLB.  If the Remove is not usable is it simply calling Delete on the child object and manually removing it from the list.

 

ajj3085 replied on Friday, February 06, 2009

Post all the code for your ERLB subclass.  Also post the exact exception and stacktrace information.

Also post all the code for the root class contained in the ERLB subclass.

rsbaker0 replied on Tuesday, February 03, 2009

Well, at least in my current implementation, all of the non-collection objects can be either root or child objects. I'm not using switchable objects per se (at least not as I have seen them described). If I want to put them in a collection, then the Fetch method just has to mark them as children and assign their Parent. Otherwise, they are roots.

Also, while it seems to me that there is at least a strong tendency for the actual instances of collections in the CSLA examples to be concrete non-generic types (e.g. ProjectResources) mine are generic more often than not (e.g. mine would be MyBusinessListBase<Resource> or something similar).

I'm sure there are potential problems with this approach, but I haven't run into anything yet I can't manage. The main issue is that it's possible for more than one *copy* of (not reference to) the same object to appear at different levels in the object graph, but in practice that requires some creative navigation through the UI.

I'd certainly be very interested if someone has specific reasons why this is ultimately doomed to failure.

That being said, I completely understand the rationale here for building separate objects for each use case. However, it's a question of resources. I don't currently have the luxury of having different classes which are (at least from our current use) apparently identical in almost every respect except for (1) whether or not they have a parent, and (2) what Type is the parent?

 

Copyright (c) Marimer LLC