When to create a new CSLA business class

When to create a new CSLA business class

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


bpb2221 posted on Friday, January 09, 2009

I am running into a situation where I have more than one way to retrieve data for a BusinessBase or BusinessListBase class.  Most of them have more than one criteria object.  Since the DataPortal_Fetch is overloaded to accept only one criteria, what do you do if you want to have multiple methods of fetching objects?

Do you override the subroutine?
Do you create a whole new class to get the data?
Or am I over thinking this and I should just create an extra function in my class (BusinessBase or BusinessListBase)  to retrieve my data?

A good example would be fetching an object(s) between two between certain dates.

Thanks in advance.

ajj3085 replied on Friday, January 09, 2009

I'm not sure I follow... you can have:

DataPortal_Fetch( SingleCriteria<MyBB, int> idCriteria );
DataPortal_Fetch( SingleCriteria<MyBB, string> partNumberCriteria );
DataPortal_Fetch( SpecialCriteria criteria );

etc.  and the dataportal will use the appropriate one.

bpb2221 replied on Friday, January 09, 2009

Hypothetical situation: Lets say I have a WaterBottles class (BusinessListBase).

I have two ways to get a collection of WaterBottle (BusinessBase) objects .  I can find them by unique water bottle id or by the date produced between two dates (ie return all water bottles produced between 1/1/2009 and 1/9/2009). 

Would you have two fetch methods in your WaterBottles (BusinessListBase) class?

JoeFallon1 replied on Friday, January 09, 2009

Yes.

Many of my list clases have multiple Shared methods.

In my dataportal fetch I call a Private Fetch method after I figure out the right SQL statement from the various options/crtieria. So all each method does is tka ethe criteria and buid the right command and then they all "funnel down" to the same Fetch method which executes the command and fills the collection.

A key assumption here is that each of the different commnads fills the complete object. You can partially fill an object but should provide default values for null fields in that case.

Joe

 

SonOfPirate replied on Saturday, January 10, 2009

To play the role of OO advocate...  Take a look at the model you are using and assess the use case and behavior for your class when retrieved using the two criteria.  Are they the same?  If not, then consider that you should probably have two classes.

Perhaps, for instance, the first case where you retrieve the WaterBottle by ID is used to edit the properties of a WaterBottle instance whereas the case where you are using the production date in your criteria is part of a search.  These are two distinct use cases and OO evangelists would proport having two classes.  In my case, I would have a WaterBottle class with a Fetch by ID that is used for editing then have some form of a SearchResultsList that contains read-only, lightweight WaterBottleInfo instances.  The list would be responsible for retrieving the items by production date and making the list available to your UI.   Your UI could instantiate a WaterBottle instance from the ID property of a child item if necessary.  This is the pattern used in the ProjectTracker sample app.

bpb2221 replied on Monday, January 12, 2009

Thanks for the answer SOP.

I know the purist will say separate it all.   When I show people the two classes for a read-only combobox (Info & List), like sample project in the book, people are thinking it is over engineered.   I agree with you though and think that functionality should be separated. 

When you refer to a 'lightweight WaterBottleInfo instances', do you mean an instance of the water bottle object with less properties than what the class defines?

ajj3085 replied on Monday, January 12, 2009

Is the use case really different though?  Whether finding by unique id or date range, you're still asking for a list of results and the same list will be displayed the same way with the same data. So i'd say simply have overloads of your factory method.  Of course if the use case is to go right to the editable object in the case of the unique id, your UI should know to call the factory method on the BB class, but that's because you're opening a different screen.

bpb2221 replied on Monday, January 12, 2009

@ajj3085:
Here is a more explicit explanation of what is going on with the Water Bottle objects.

The unique ID would be for an editable business base.  So it would pull every property of the Water Bottle object.  This would be passed to a datasource on a form for editing.

The collection (between two dates) would be for a report.  It would not pull every property of a Water Bottle object into the collection.  This would be passed as a read only collection to a datasource on a report.  In my case, ActiveReports.

In your opinion, would these two situations warrant two different classes?


ajj3085 replied on Monday, January 12, 2009

Well, it sounds like two use cases.

One you enter criteria (the unique id) and the user expects that water bottle to be dispalyed on screen for editing.  So your WaterBottle would subclass BusinessBase and have a static factory that gets by id.

The other use case is that you're looking for all matching waterbottles.  In that case, I'd think you'd have a WaterBottleList : BusinessListBase<WaterBottleList, WaterBottleInfo> and WaterBottleInfo : ReadOnlyBase.  The list class would have a factory method that takes the search criteria.  Of course, if you want the list to display even you enter the unique id you'd have a factory method for that as well.  For example maybe they just need the "summary" the WaterBottleInfo providers and don't need to use the fullblown editable WaterBottle.

HTH
Andy

maxal replied on Monday, January 12, 2009

I would create my own criteria class with all necessary properties and then have one DataPortal_Fetch method to analyze this criteria, doing the fetch one way or another.

SonOfPirate replied on Monday, January 12, 2009

Andy's description of a WaterBottleInfo class is what I meant by lightweight object.  It could have the same properties but none of the BO methods, etc. Since it is designed to simply display a list of water bottles in a list or grid, you can limit it to the properties that you want to display.  The list manages all interaction.  All you need is to bind each row to the same Unique ID that you will use to instantiate the individual instance of your WaterBottle class (BO) for editing.

Copyright (c) Marimer LLC