business objects dilemma: read-only vs read/write

business objects dilemma: read-only vs read/write

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


opedog posted on Friday, August 14, 2009

I'm part of a team tasked to revamping our old VB6 UI/COBOL database application to modern times.  Before I was hired, the decision was made (largely on sales, I'm sure) to redo the UI before the database.  So, now we're using WPF and MVVM to great effect, it's been amazing so far, especially using CSLA as our Model layer.

However, because our development is side-by-side with the next version of the old product, we're constrained a bit.  We can't make any changes (or minimal changes) to the calls made to the COBOL database.  This has been fine so far, albeit pining back to the glory days of SQL Server if you can believe it.

Where I've hit a particularly nasty roadblock regarding our BO design is in dealing with "light" business objects returned in lists and their "full" counterparts.  Let me try and construct an example:

Let's say we have a person object in the DB with a bunch of fields.  When we do a search on that table, we don't return all the fields, so we populate our lite object with these.  These fields may or may not be a subset of the full person.  We may have done a join or two to retrieve some other information specific to the search.  But, if we want to edit our person object, we have to make another call to get the full version to populate the UI.  This leaves us with two objects and attempting to juggle their state in 1 VM, all the while trying to keep the person list in sync on whatever parent object it sits after delete, edit, and add.  Originally, I made our lite person object derive from ReadOnlyBase<>.  But now that I'm dealing with the same list behavior you'd have with a list of full BOs except with half full, half lite, I'm thinking I should've just made both the lite and full versions derive from BusinessBase<> and simply made the lite version setter properties private.

Has anyone else out there come across and found a solution for this?  After sleeping on it, I've come up with this potential solution.  What if we wrap the full and lite version of our BO in another BO, like this:

public class PersonFull : BusinessBase<PersonFull>
{
  ...
}
public class PersonLite : BusinessBase<PersonLite>
{
  ...
}

public class Person : BusinessBase<Person>
{
  public PersonFull PersonFull;
    public PersonLite PersonLite;
}
public class PersonList : BusinessListBase<PersonList, Person>
{
}

Obviously everything would be CSLA registered properties and such, but for the sake of brevity they're fields there.  In this case Person and PersonList would hold all the factory methods.  After a search operation PersonList would be populated by Person objects whose PersonLite members were all populated and the PersonFull objects were all null.  If we needed to get the full version, we simply tell the Person object to do so, and now we have our PersonFull object so we can populate the edit UI.  If the Person object is to be deleted, we can easily do this with the CSLA delete procedures in place, while still maintaining the integrity of our lists across all the VMs that are listening to it.

So, I hope this made sense to everyone, and if anyone has a different solution they've successfully employed or criticism of this one, by all means!

Thanks!

(repost from: http://stackoverflow.com/questions/1278697/c-csla-business-object-dilemma-read-only-vs-read-write)

pondosinat replied on Friday, August 14, 2009

I've seen the approach in a WPF app where the search results grids are populated with the full blown editable objects, which could then be opened up and edited. I've also worked with the Readonly list approach you mentioned earlier. Design wise, I think the latter makes more sense because the read to write ratio tends to be very imbalanced -- people are usually constantly searching your objects, but only open up to edit maybe 1% of the objects they've searched. Readonly lists are much more lightweight then even small editable objects. So scalability becomes a big issue.

Of course, I'm over simplifying a bit since this is a general question. HTH.

opedog replied on Friday, August 14, 2009

Right, but the dilemma comes in when I need to edit one of my read-only objects, so I do a full get from the DB.  Then what?  Now I've got 2 copies of the same data in 2 different places.  After the edit's save, now I've got 2 copies of different data in 2 different places.

The same goes for a delete.  I display my list of read-only objects in the view with the option for the user to delete them, but when they do I'm constrained by the ReadOnlyListBase<> inability to delete objects.  Sure, I can remove objects from ROLB by adding a remove method and make it call a delete function on the BO or something, but I don't want to have to do that more than once and I have several of these lists with similar behavior.

It's the same with an add.  You have to force an add into a ROLB, and even then I'd have to go through the process of converting a full BO into a lite one, which would be a pain in itself since the lite version is a ReadOnlyBase<>.

So, I'm thinking I'm limiting myself here by using ROB and ROLB.

Copyright (c) Marimer LLC