Persisting data from a control to a database

Hi all,

I'm having an architecture problem with an Smart Client app I'm trying to write, i.e. separation of BL and DL and who does what. Please feel free to redirect me to any books, online articles for object oriented design for n00bs if you need to.

I basically have a sub-classed picturebox control with a couple of extra fields and methods. I want to persist the data in the extra fields to a database, along with the image itself. My question is, where would the Save method go?

If it's on the object (my sub-classed picture box), the object would need to reference the DLL classes in order to Save itself. That's ok, but that also means that I would need a Create method on the object as well, or handle the creation (and saving) of the object in a specific constructor.

I was thinking of a PictureManager class, which would be responsible for the data operations on the picturebox object, i.e. creating one, saving changes to it, etc., so you would just have picManager.Save(pictureBox); in code - is that acceptable?

Basically, coming from a VB 4 - 6 background, my OO kung fu is not as strong as it could be. I "get" OO, and I'm taking (or trying to take) an OO approach to this app, but as usual I am having trouble figuring out which object should do what - in this case, which object is responsible for saving data.

Any advice would be great, or if I've not made myself clear please let me know.

I could obviously code all this in the client using strongly-typed datasets, but I'd rather avoid that.

Thank you,

Mike Kingscott

[1616 byte] By [MikeKingscott] at [2008-1-5]
# 1

Ahhh...the perennial debate, Domain Model vs Transaction Script vs Table Module vs Service Layer. Here's the thing, they aren't always mutually exclusive. Your Domain Model object can have a save method that calls save on the service layer, which hits a transaction script to save the object, which then uses the table module.

Or you could have your ui call the service layer which takes the domain model passing it to a transaction script which .... okay I guess you get the picture.

The domain model works well because your root domain object could expose the Save function and it would know how to persist itself either directly or using another object or layer. The important part is that the caller doesn't get involved with the details of the implementation. This way, you can switch how it's done on one layer and the only person that cares is that layer itself.

So you have an abstract class Picture that defines a save function and a static load function (no constructor). Both the save and load function call to the service layer...which handles saving the object and loading an instance and returning it based on parameters. Let's say down the road you switch from using a database to save and load pictures to using a webservice, like flickr. The only change you would have to make is to the service layer. And if the service layer was developed against an interface, you could keep the old service layer and swap it with the new FlickrPictureService based on configuration.

A great book to read for guidance on architecting enterprise applications is Martin Fowler's Patterns of Enterprise Application Architecture. The first section of the book is a great narrative of some of the situations one might encounter when developing enterprise apps. After that is a pattern catalog, each pattern containing wonderful examples of when it might be useful.

Hope this helps!

ivolved_Mike_Brown at 2007-10-3 > top of Msdn Tech,Architecture,Architecture General...
# 2

Mike, thank you very much for your reply - and those helpful links ;-) I understand (I think) what you are alluding to with the domain model (2nd para), I think I need to digest it a bit more... It's really annoying, I keep on flipping from having the subclassed PictureBox object save itself to a manager (the service) saving it instead, which I think is what you're suggesting... :-s

Thanks again, I'm currently looking on Amazon at that book you recommended.

Mike K.

MikeKingscott at 2007-10-3 > top of Msdn Tech,Architecture,Architecture General...
# 3

Hello again Mike,

Ok, my design has come along a bit. I'm going for a Domain Model approach as suggested, which will pass off the db gubbins to a Service Layer. I have several methods on the MyPictureBox object (Save for an instance, a static Create [from parms]), and I think I understand that your suggestion of a static load method should return a populated MyPictureBox based on parameters passed into it. For the static Load method method, I'm taking in the all the necessary parms to set the MyPictureBox object up (just the db id) and using a private constructor to set the private member variables. I also have an overloaded Load method to retrieve only certain MyPictureBoxes from the database; it returns an array of PictureBoxes.

Am I doing the right thing by using the private constructor to populate the MyPictureBox? It does prevent the end developer from creating it willy-nilly and it *does* compile and work ok ;-) I was wondering whether it is more OO to create an blank MyPictureBox and set its values through properties, but that's just more trips to the object rather than an "all in one" hit.

Thanks for your advice, I've just hit the nail on the head I believe :-)

Mike Kingscott

MikeKingscott at 2007-10-3 > top of Msdn Tech,Architecture,Architecture General...
# 4

I'm glad I was able to help you come further along...but what I was suggesting for the Load function was that it be placed on an abstract class (like PictureBoxBase). It would basically call into the service layer which would be responsible for creating an instance of a Concrete implementation of PictureBoxBase. This is what will provide true decoupling, because like I said your service layer could return a FlickrPictureBox one call and a SqlPictureBox the next and the UI wouldn't care as long as they Implement PictureBoxBase Save() would be declared abstract, requiring the concrete subclass to implement it.

But for now your usage of the private constructor is definitely a step in the right direction. If you have the opportunity, also consider picking up Design Patterns by a group of writers that the industry affectionately call the Gang of Four. Specifically, you'd want to read up on the Factory pattern. It goes hand in hand with what you're doing here.

ivolved_Mike_Brown at 2007-10-3 > top of Msdn Tech,Architecture,Architecture General...
# 5

Hello again Mike, thanks for your reply. It might surprise you to know that I am actually aware of the factory pattern, and I understand what you are patiently explaining to me about the abstract base class - someone previously explained it to me, although it took them much longer as I'm quite dense ;-)

For the moment, I'm going to stick with the SqlPictureBox only approach (i.e. my private constructor approach). However, you have set me thinking about whether I do want to create an abstract base class to allow for future development... It certainly would make sense. I assume in the post above the service layer contains the factory? It's been a while since I've used one...

Thanks again, I really do appreciate it.

Kind regards,

Mike K.

MikeKingscott at 2007-10-3 > top of Msdn Tech,Architecture,Architecture General...
# 6

Mike,

Sorry if you felt I was talking down to you. It's a difficult line to tread between giving someone enough information to answer their question without assuming too much. No, I wasn't assuming you were dense, but I also didn't want to get too far ahead of you and have you swimming in a sea of information.

To answer your question, the load method would be on the abstract base class but yes it would delegate the actual creation to the service layer.

ivolved_Mike_Brown at 2007-10-3 > top of Msdn Tech,Architecture,Architecture General...
# 7

Hello Mike, I certainly did not feel you were talking down to me at all, I guess my sense of humour does not translate well in text. As for me swimming in a sea of information, if you hadn't have posted those links to Martin Fowler, I would still be stuck :-)

Regarding that Load method on the abstract base class and its delegation to the service layer, can I assume we're still talking about data retrieval? I would code it like so:

MyPictureBox pb = MyPictureBox.Load("ABC"); // ABC is a database id

Load is still a static method and it returns a new MyPictureBox. If I'm using the factory pattern, where does the decision to use Flickr or SQL come into it? Surely not in the static method... My understanding of the factory pattern would be:

MyPictureBox pb = MyPictureBoxFactory.GetPictureBox(); // MyPictureBoxFactory contains logic from config file to create FlickR or SQL pic box

pb.Load("ABC");

However, in the above I've lost my static Load method as it's now on the instance rather than the class - is this ok, as in your earlier post you said "So you have an abstract class Picture that defines a save function and a static load function (no constructor)."?

Phew... My other question is where would I go if I wanted a just an empty MyPictureBox, ready to be filled with data and saved? I had envisaged another static method called Create, like so

MyPictureBox pb = MyPictureBox.Create("c:\my pics\pic a", "some more info");

Currently that extracts a thumbnail, calls down to the db, saves the thumbnail and other info and returns an id which I use internally on the pb instance. So, how would I do that using the Factory pattern? Would it be an overloaded method, i.e.

MyPictureBox pb = MyPictureBoxFactory.GetPictureBox("c:\my pics\pic a", "some more info"); // MyPictureBoxFactory contains logic from config file to create FlickR or SQL pic box

// I can now use pb however I want...

Hmmm, I think that might be it - am I right?

Thanks again, I do appreciate it and do please assume I'm dense - as I said, it took the other chaps quite a while to explain it to me...

Mike K. (who has a headache now)

MikeKingscott at 2007-10-3 > top of Msdn Tech,Architecture,Architecture General...