Help with "switchable" objects...

Help with "switchable" objects...

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


NickTaylor posted on Wednesday, September 16, 2009

Hi,

I wonder if some wise person can assist me with this please...

I have a simple root business object that in turn contains a child collection. For the sake of simplicity, let's call the root object "BoCustomer", and the child collection "ListBoCustomerContacts". As far as the business logic goes, BoCustomer will always be a parent object and is not required to exist in any form of collection. The child list, i.e. ListBoCustomerContacts contains a bunch of BoCustomerContact objects which will always be child objects and will never exist in their own right. All faily clear cut...

However, as part of my Winforms UI, I wish to display a bunch of customers in a grid ( mainly for the purposes of navigation ). Previously I had queried the database with something like "SELECT * FROM CUSTOMERS", and used the resulting datatable to populate the grid directly within the UI. Note that I am not bothered about the contacts at this point. It worked fine, but its not clean as this sort of stuff shouldn't really be in the UI should it !?

After a few discussions on this forum it is suggested that what I should be doing is using a customers collection to return the bunch of customer objects, and then bind to this in the UI. I would expect to create an editable root collection object that can be used to hold my BoCustomer root objects, and provide this with a method such as GetAllCustomers() which populates itself with a BoCustomer object for each customer in the database. But in doing this I have now made the BoCustomer object switchable haven't I ? I now have to have a collection object, and both root and child code within BoCustomer? This seems a bit excessive and the book advises against using switchable objects unless absolutely necessary.

So really the question is how do I return simple lists of things which are really only being used by the UI, and are not part of the business logic ?? Is it a case of a collection for everything, or does my original method of simply querying the database still have a place...?

Any suggestions would be most welcome...

Thanks,

Nick

dlambert replied on Wednesday, September 16, 2009

I've usually ended up creating a "lite" read-only version of these sorts of objects for use in lists, search results, etc., with the understanding that if someone wants to navigate to a "real" edit screen for this object, you'd load the "real" object for editing.

So, depending on what you want to do naming convention-wise, you might end up with:

* Customer -- this is the fully-editable object.
* CustomerInfo -- this is a lite, read-only version of Customer. You can make this as big as it needs to be for your lists, but keep in mind that you'll be creating these in quantity, so it pays to keep it skinny if you can.
* CustomerInfoList -- this is a collection of CustomerInfo.

rsbaker0 replied on Wednesday, September 16, 2009

NickTaylor:
...But in doing this I have now made the BoCustomer object switchable haven't I ? I now have to have a collection object, and both root and child code within BoCustomer? This seems a bit excessive and the book advises against using switchable objects unless absolutely necessary...

My experience has been root objects work just fine as children -- you just have to call MarkAsChild on them when they are fetched. If you have an intermediate class layer you derive from instead of deriving directly from CSLA classes, this isn't hard to do.

I think the argument against doing this is based on use cases and that the need to do so calls the design into question -- the rules and and behavior may be different in the child scenario versus the root, and often when you are trying to use a root as a child what you really should have is an object that is specific to the relationship between them.

 

ozitraveller replied on Wednesday, September 16, 2009

For something as simple as this I'd probably use a DataTable particularly if there is a lot of data and only load a bo when adding/editing savable data.

ajj3085 replied on Thursday, September 17, 2009

Yes, thats the arguement against switchable designs. Basically it can lead you to a point where you're doing:

if ( IsChild ) { do this } else { do this }

which leads to hard to maintain fragile code.

NickTaylor replied on Thursday, September 17, 2009

Thanks to all for the responses...

I think for the time being I will stick with just returning a datatable and using this within the UI. It is the simplest solution for now. I quite like the idea of the lite collection and lite business object as this isn't something I hadn't considered. This is one for the future perhaps...

I guess in the true sense of the word my BoCustomer object isn't really switchable as it would never be used as a child and therefore we avoid any potentially messy business logic. I can now see why this scenario is best avoided. Its merely a child when its loaded as part of a collection and perhaps adding the code to load BoCustomer from a datareader isn't such a big deal after all.

Many thanks,

Nick

ajj3085 replied on Thursday, September 17, 2009

Be aware by doing this you lose one of the benefits of Csla, which is the ability to switch easily from a 2-tier deployment to a 3-tier one.

The "light" type objects are very easy to build, I would recommend taking the time to do so... you'll save yourself headaches in the future, especially if your data layer changes.

NickTaylor replied on Friday, September 18, 2009

Yes, you are right... We are undoubtedly going to change our database in the future as we are currently working with legacy FoxPro data and will want to move this to SQL later down the line. My simple SQL statement should have a "light" list and "light" business object associated with it. I can create these with some object factory code, so as you say, creating these objects should be easy. I can then use the "light" list to populate combos, grids, etc...

Many thanks!

Nick

david.wendelken replied on Friday, September 18, 2009

Ok, how does the light object work in the grid in this situation?

A business object has 20 properties with complex logic to validate.

We're using an asp.net web page for the UI.

We'll assume the presence of a full-featured edit page somewhere using the full "heavy" business object.

On another web page, the user wants to show a subset of those objects and just 4 of those properties in the grid.  The user wants to be able to change those properties directly in the grid, not go to another page to change the properties.

There might be several of these pages, with slightly different filter criteria and a slightly different set of 4 to 6 properties.

I don't want to duplicate business rule code across multiple objects.

What to do?

 

ajj3085 replied on Friday, September 18, 2009

Hmm.. that's more tricky. The "light" objects above I believe were simply readonly objects used to present some data, not edit. Your scenario sounds different.

Honestly, probably your best bet is to code everything seperately, then refactor common code into shared (probably internal) classes. If you're really careful, you can probably do this at the design layer.. design your BOs to fit uses cases, identify any common functionality, then redesign add the shared classes.

The filter criteria shouldn't matter.. you shouold be able to reuse the same classes and provide different factory methods, or dirctly expose criteria classes. Different properties though will likely require different public classes.

ajj3085 replied on Friday, September 18, 2009

Well, then creating the objects now is the right choice. Later when you decide to move, you can simply update the DataPortal_Fetch and Child_Fetch code, and that's all you'll have to do!

david.wendelken replied on Friday, September 18, 2009

ajj3085:
Well, then creating the objects now is the right choice. Later when you decide to move, you can simply update the DataPortal_Fetch and Child_Fetch code, and that's all you'll have to do!

I'm confused.  :(

Was that an answer to my question?  Because I truly don't understand what you're trying to tell me if it was.

Edit Note:  Ok, I see your second post now.  Happy, happy. :)

NickTaylor replied on Friday, September 18, 2009

I'm just using a very simple light list based on ReadOnlyListBase and a light "business object" based on ReadOnlyBase ( with a Fetch(dr) method only ). Obviously these only need minimal code, and they dont overlap any code already present in the true business object. I am only using it to populate grids etc in the UI, and so far it seems to work pretty well.

Nick

Copyright (c) Marimer LLC