Letting Go of the DataPortal

Letting Go of the DataPortal

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


jtradke posted on Monday, February 04, 2008

So, following the discussion in this thread, I'm experimenting with using CSLA.NET without the DataPortal, using my own wrapper to IBatis.NET in its place.

Advantages (so far):
1) Uses IBatis.  Very familiar throughout my organization, supported by existing apps, etc.
2) No need to implement DataPortal_Fetch.  BO's would have static factory methods which call a method on my Repository static class (much like they would normally call DataPortal.Fetch).
3) No need to implement DataPortal_Insert, Update, Delete, DeleteSelf.  My base abstract business class (which inherits from CSLA's) would take care of calling the appropriate method on the Repository class, which would use the BO's type to determine which IBatis statement ID to use.

Disadvantages (so far):
1) We'd have to duplicate some CSLA functionality.  Makes upgrading hard, if that stuff changed in the new version.
2) We wouldn't be able to switch to 3-tier mode on the fly.

I'll respond to the disadvantages below, but I think there was a misunderstanding of what IBatis does in the previous thread.  The BO need not be modeled on the data structure at all.  IBatis doesn't map a table to a BO or anything like that, it maps a QUERY to an object.  I could have ten different business objects all selecting off of the same table in different ways based on use case, if I wanted.  That would indicate a pretty crappy datamodel, but that's kind of the point - IBatis helps you de-couple your nifty modern object model from your nasty legacy data model.

So, disadvantage #1 - upgrading CSLA: certainly that would be challenging, but there's not a whole heckuvalot of duplicating.  BusinessBase and BusinessListBase call DataPortal.Update() in their Save() methods, so I would just have to mimic what DataPortal.Update() and Business[List]Base.Save() do, as far as I can tell.  I don't think there's much else - business objects normally call DataPortal.Fetch() in their factory methods, so I would just call Repository.GetListOf<Widget>() or such instead.

Disadvantage #2 - The Three-Tier Potentiality.  If we ever found ourselves strolling down that path, I'd probably just switch everything over to the DataPortal at some level, and then deal with the complexities at that point - it's just that I don't want to deal with it now, when there's a pretty low risk of the TTP occurring anytime soon.  In terms of planning for such a thing, I would want to de-couple the data-access stuff from the business stuff *anyway*.  So then the changes involving the DataPortal would be limited to confined areas.

I'm still convinced that the Three-Tier Potentiality is highly unlikely.  If there were an initiative for that sort of thing, it would probably be aimed at other, bigger, more widely-used, more database-contentious applications than the one I'm assigned to.

webjedi replied on Monday, February 04, 2008

jtradke:

I'm still convinced that the Three-Tier Potentiality is highly unlikely.  If there were an initiative for that sort of thing, it would probably be aimed at other, bigger, more widely-used, more database-contentious applications than the one I'm assigned to.

In my experience the smaller projects are the ones that are guinea pigged for the larger ones. :-)

Ryan

tmg4340 replied on Monday, February 04, 2008

Let me start by saying that my knowledge of iBatis is passing at best.  I looked at it a little while ago for a project I was working on that was leaning towards using SQLCE as its backend.  I ended up passing because I couldn't see a way for iBatis to run multiple SQL statements for a particular operation, which I would have needed.

In any event - I have to admit I am somewhat confused here.  It seems that what you've done is taken the DataPortal - a technology that is very tightly integrated with the CSLA business-object concept - and replaced it with the same thing.  The DataPortal, and the accompanying DP_ methods, are essentially where your data mapping takes place.  The static factory methods that call your Repository class would be replaced by... static factory methods that call DataPortal methods, which eventually resolve back down to the DP_Fetch method in your BO.  Instead of overriding the Save() method to call out to your Repository class, and re-engineering significant portions of the DataPortal code to determine whether you should issue an INSERT, UPDATE, or DELETE, you could simply let the framework do its thing and implement the other DP_ methods.

There have already been discussions about what you lose if you bypass the DataPortal, and you've even acknowledged that if you end up moving torwards an n-tier solution, you'll probably just move back to using the DataPortal.  So, at least to my mind, all that work you've done to bypass it in your two-tier scenario makes even less sense, since in the unlikely event you do have to make the change, you have to chuck everything you've done.  And while you may not have duplicated much of the DataPortal now, there are some pretty significant DataPortal changes coming down the pipe with 3.5 in the way of automatic child management and some other things.  I'm sure you can update your customized solution, and maybe it already handles that.  But it could be a lot of code to update, since he's also drastically changed property management in order to do these cool things.

Granted, with iBatis you have some separation of your ORM, since it's contained within an external mapping file.  But using the DP_ methods gives you the same thing, without having to include the additional iBatis DLL's and external mapping file(s) - not to mention the ability to protect some of your BO data (since iBatis uses reflection, all your properties have to be read/write.)  Sure, having the mapping files gives you flexibility - but do you really need that flexibility once you've gone to production?  Your SQL mappings generally don't change once the app is deployed.  And yes, you haven't embedded all that ORM grossness within your BO's, thus producing a more loosely-coupled design.  But I'm not sure what that gains you, since the ORM you place in the mapping files is specific to your BO design, and thus is not likely to be re-used without the BO as well.

I'm not knocking iBatis as a product - it seems to be pretty good, and as I said, I don't know much about it.  And I will admit that not having to write all that boilerplate DAL code is nice, though you can get around a lot of that with a simple DAL and some judicious use of the DataMapper, and create a design that's just as loosely-coupled as what you have now (just because the DataPortal calls the DP_ methods for data access doesn't mean those methods have to have a bunch of DB-specific code in them.)

You seem to be writing an awful lot of code to replicate what the framework already gives you.  So what am I missing?

- Scott

jtradke replied on Tuesday, February 05, 2008

Hi Scott, thanks for the reply.  I think generally, though, I'm not replacing the DataPortal with the exact same thing - I'm replacing it with something that has less indirection.  With the DP, you call an object's Save() method, which then calls DP.Update(), which then goes back to the object and calls DP_Update() or DP_Insert() or DP_DeleteSelf().

With this Repository I'm suggesting, object.Save() would just directly call Repository.Insert() or Update() or Delete() (the logic for determining which persistence method to call would be in a base class).  This is more straightforward and intuitive in my mind.

When the DP and the object exist within the same memory block, I believe the back-and-forth calling is a strange thing to encounter as a business developer, and is not needed.  I understand that the motivation is to be able to flip a switch and enable 3-tier, but to me that is like walking with crutches on two good legs while awaiting a broken leg - i.e. fixing what ain't broke yet.  Or more accurately, catering to a requirement which does not exist yet.

The underlying issue is really that the DataPortal is the only part of this framework that gives me pause.  I've read most of the book and this is an insanely useful product which Rocky has put together.  However, I can't quell that feeling that the DataPortal is violating the YAGNI principle - You Aren't Gonna Need It, referring to coding to requirements which may or may not materialize, needlessly complicating the design when it's not entirely necessary.  Further, I'm concerned about selling this idea to my coworkers who will be utilizing the framework along with me.

Am I just crazy?  I'm certainly not attempting to bite the hand that feeds me (if you will), but I want to raise the question in order to get some knowledgeable feedback on these concerns.

ajj3085 replied on Tuesday, February 05, 2008

well, if you use only the local portal, the reflection and indirection are minimal, compared to other actions you'll be doing like database access.  Additionally, keeping your data access code restricted to those few methods keeps you from bleeding data access into other areas of the BO. 

While its true you may not ever need it... you're not the one building it.  YAGNI applies more to what you're building than what comes bundled in a framework.  If everything BUT the DP is useful, that's alot of  benefits.. you get one feature you don't care about, but many you do. 

Right now, you're doing work to avoid it instead of just using it as is.  By your own admission, you haven't really changed much... so why do anything at all at that point and just use it as is?

Just my thoughts.

jtradke replied on Tuesday, February 05, 2008

Very good points ajj3085, thanks for the input.  Fortunately these decisions are not urgent, so I'll have some time to mull it all over.

ajj3085 replied on Tuesday, February 05, 2008

Ha, well, I can't really take credit for them.  Rocky was the one that originally made these points in response to similar remarks about Csla.  I find them to be valid though, and one of the nice things about frequenting this forum is that reading these kinds of debates helps me "see the forest through the trees," so to speak.

My last comment will be that I'm not trying to get you to necessarly change how your doing things, its more of looking at Csla as a whole and keeping in mind things like maintenance, possibility of n-tier (I know, it won't happen, but think of it this way.. what a great selling point for your decision to use Csla knowing that you could move to n-tier without changing your code, and if you never do, the impact is minimal) and reduced code that the framework enables.
 
If you conclude what you're doing now is fine and the "risks" presented are small for your application there's nothing wrong with your approach.

tmg4340 replied on Tuesday, February 05, 2008

jtradke:
The underlying issue is really that the DataPortal is the only part of this framework that gives me pause.  I've read most of the book and this is an insanely useful product which Rocky has put together.  However, I can't quell that feeling that the DataPortal is violating the YAGNI principle - You Aren't Gonna Need It, referring to coding to requirements which may or may not materialize, needlessly complicating the design when it's not entirely necessary.  Further, I'm concerned about selling this idea to my coworkers who will be utilizing the framework along with me.

Am I just crazy?  I'm certainly not attempting to bite the hand that feeds me (if you will), but I want to raise the question in order to get some knowledgeable feedback on these concerns.

I don't think you're crazy.  I had similar issues when I first looked at CSLA.

As Andy has already commented on, I don't think YAGNI applies as much here, since it's not your code.  In a local scenario, you're not going to notice much.  Sure - you're travelling through a couple of different classes to get back to your BO.  But I don't see it as any more complicated than what you've built using your base class and Repository.  That was the main thrust behind my comment that you're building the same thing.

(Yes, there are a lot of other options available, which adds to the complexity of the situation.  But if you don't need them, you don't use them, so they don't get in the way.  As such, I'm not counting that complexity as part of this discussion.)

As far as what the DataPortal does, consider that one of the basic tenets of the framework is that it's for programming distributed enterprise applications.  The need to easily swap from a two-tier to an n-tier situation - or from one n-tier style to another - was big requirement for him, and for a lot of other folks too.  In my work, we don't do n-tier for the CSLA stuff, and we have no looming requirement to do so - in fact, we're more likely to go SOA than a classic n-tier situation.  But I still use CSLA, and will continue to do so even if we go SOA.  The fact that the DP can work fairly seamlessly in all these situations is a big bonus for my ability to respond to both my users and the architectural changes going on around here.

As for selling the concept to your co-workers - well, I keep coming back to what others have said before: you either buy into the framework or you don't.  The DataPortal is integral to how CSLA works, so if you're going to use CSLA, this is how you use it.  It is this comment that got me past my initial questions, and as I looked at it more (and was exposed to different environments), I began to really see the usefulness of the concept.  I don't see it as an overly-complex design, and the benefits it provides - even though you aren't going to be taking advantage of all of them - are tremendous.

HTH

- Scott

jtradke replied on Tuesday, February 05, 2008

Thanks for the input Scott.  Good stuff.

Copyright (c) Marimer LLC