Design Issue - Uses Case

Design Issue - Uses Case

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


griff posted on Thursday, November 08, 2007

Hi

Another design issue I have.

I need a ro object to populate a screen and for use in sending details via email .
The data required exists in several tables that are all related (parent/child etc).

tblJobs--->tblJobDates---->tblTimeSheets---->tblStaff
tblJobDates--->tblVenueDetails
tblJobs----->tblClientDetails
tblJobs----->tblPatientDetails
tblJobs----->tblSubClientDetails

So I can't decide what to do.....in this instance I will be pulling back 1 record only (and child records)

1) do I simply design a stored proc to pull back all relevant data from the table and populate a ro object.

Pros: easiest to do, best performance

Cons: user requests additional fields so a need to amend st.proc and ro object, little reuse maybe elsewhere in the application

2) Design a larger ro object that loads the full ro child objects into it

Pros: Have access to all fields in child objects so as requirements change should be able to deal with easier... also ro child objects can be used elsewhere in the app.

Cons: slower performance (but is this the case as I intend to pull back only 1 parent record), overkill in that I have large class object from which I really only need access to 20 or so data items out of several hundred say.

Anyone had similar?

Thanks

Richard


JonStonecash replied on Thursday, November 08, 2007

This is one of those cases where "it all depends".  You have mentioned some of the factors, but let me add a few more thoughts.

First, my preference is to have the "leanest" possible implementation that will satisfy the use case.  If the use case changes, then that "lean" implementation must be changed explicitly to adapt to the change in the use case.  The lean version should be much easier to understand, much easier to unit test, and much easier to debug: there are simply fewer moving parts to deal with.

Second, on the other hand, there may be some unstated requiements in the use case that require "very rapid response" when the requirements change.  Those requirements may direct you down the path that says add a few of the more likely extensions but nothing like "select * from everything".  If you cannot figure out what the "likely suspects" are, I would recommend doing nothing.  Wait for the change and accept the fact that it might take a while.

Third, beware of reuse that springs from a desire to save code.  As soon as you employ the same (non-utility) class for two or more use cases, you are risking the coupling of all of the use cases that use that class.  When one of the use cases changes, then what do you do?  You can, of course, perform some detailed analysis to see what the impact of the change would be on all of the use cases but that takes time and testing and entails the risk that you did not catch all of the problems that it causes.

This is a balance between maintainability and enhancibility.  Good maintenance practices push you in the direction of "leanness" and "low coupling".  Good enhancibility practice also is built on low coupling but should involve other practices such as code generation and components.

Jon Stonecash


rsbaker0 replied on Thursday, November 08, 2007

Maybe you could just "lazy load" the child objects. The child reference in the object starts out null, and when the property is first accessed, you load the child object and return it.

This has the advantage of flexibility and not loading child data that won't be referenced unless it is needed.

griff replied on Thursday, November 08, 2007

Hi
the lazy load won't work here as I will need to access some of the data items in all child tables - so I do have to load everything.

The lean option does sound possibly right, my only concern here is that several of my tables/objects similiar requirements such as formatting the address correctly (client, patient, venue etc) and names (title, lastname etc) - I could do this in the st. proc but I know I will re-use this functionality each time I want to interact with a client, patient, venue etc. so I am thinking that the ro object can contain this functionality and be available next time I interact with that object.

As you say 'it all depends'

Richard

malloc1024 replied on Thursday, November 08, 2007

If you have many objects that require formatting an address, add a shared format function to the address class. Create an interface that contains the information needed to format an address. The shared format function would accept the interface object and return the properly formatted string. You can do something similar to formatting names. The behavior of formatting and address or name should only be in one class. I would not use a SPROC for this.

griff replied on Friday, November 09, 2007

Hi

being new to OO design etc.  Can you expand on the interface object.  Is this more complicated/different from simply having another object e.g. cFormatAddress that accepts address data items and formats accordingly.

Richard

DavidDilworth replied on Friday, November 09, 2007

No not really.  But using an interface would then enforce a strict contract that has to be followed wherever it is consumed.

A simple example for a Person could be:

public interface IPerson
{
   string  Title {get;}
   string  Firstname {get;}
   string Lastname {get;}
}

And then different formatting functions in your formatting class might look something like:

string GetFullName(IPerson person) {...implementation goes in here...}
string GetShortName(IPerson person) {...implementation goes in here...}

So your formatting functions don't need to know about the Type of the object that contains the properties Title, Firstname and Lastname.  It just knows there are property getters available for any object that implements the IPerson interface.

This is based on a design principle that states "Program to an interface, not an implementation".

DavidDilworth replied on Friday, November 09, 2007

And as for whether you should go for option (1) or option (2) from your original question.  

I would probably recommend option (1).  Unless you think that future requirements for the BO will be very changeable.

Adding 1 new field/property and associated SQL in your SP is not a massive re-engineering project once you've got the basic BO built.  It should be a relatively quick and easy job to do.

Design your BO to meet your Use Case.  Don't design it to meet all possible variations of all possible Use Cases that you don't actually know about yet.

You could say this advice is based on the YAGNI school of thought.

Copyright (c) Marimer LLC