locked
Architecture Advice Please - Best Practice, Smart-Client, Business Objects RRS feed

  • Question

  • Hi.

    I'd like to ask the experts here for some advice/opinions.  Specifically about business object implementation and storage.

    These are the details of my application:
    This is a Windows Forms app, developed for Windows XP using VS2008 (VB.NET).  I'm using a smart-client model.  The application is deployed with a local SQLServer CE database and I use the sync framework to synchronize data bidirectionally with a central SQL Server when a connection is available.

    The data hierarchy is important for the user so I have a menu/details type of interface.  So, basically there are menus containing treeviews representing this hierarchical data.  When a user selects something in a menu the details of that item are displayed on the main form for the user to interact with.

    I've learned my lesson about table adapters so I don't go there.  All of my SQL is in a DataAccess Class and I have many business object classes.  Translation between relational data from the database and the business objects is typically happening in my DataAccess class.  This isn't ideal but from what I've read, I'm not ready to buy into the Entity Framework thing in VS2008.

    Here's my current situation:
    I'm currently creating instances of business objects or partial objects where they are needed throughout the application.  For instance, a treeview may be created from a datatable returned from the DataAccess class and the nodes would only contain the name and ID of the record.  Meanwhile, when a user selects a node, an business object is created and the form controls are bound to it.  This seems bad because its two trips to the database.  Also, when the user updates something like the name, the treeview has to also be updated or re-loaded.

    Here's what I'm thinking about doing and my questions for you:
    I think I'd like to have a single instance of each business object that is available to the entire application while it's running.  Treenodes would contain certain properties of the object and could reference back to that object.  I think the business objects should be 'lazy-loaded' as they are required by the user.  So as the user expands a node in a menu the business objects that represent the child-nodes are created and stuffed into the in-memory list or array and the child nodes are created (with name and Id) based on those objects.  When a user clicks on a node the form is bound to the corresponding in-memory business object.

    Is this reasonable?  If so, how would you implement that?  Specifically, would the application have a some big array or list of all the business objects or something like that?  What specific list or array type would you use?  Is there a better way or something obvious that I'm missing?  This model is still going to require me to raise an event when an object is modified and update treenode appropriately, which isn't ideal but implementing databinding on the treeview may be a bit beyond my skills at this point - But I'm open to all ideas.

    Thanks so much for reading.  Any advice/references/examples/etc. are appreciated and all answers will be marked as such.

    Jason

     

    Tuesday, May 17, 2011 3:25 PM

Answers

  • Jason,

    I think you're on the right track. There is a design pattern that could be useful to you. The pattern is called Identity Map. You can find a brief description here... http://www.martinfowler.com/eaaCatalog/identityMap.html

    The idea behind an Identity Map is to store all objects retrieved from the db in one collection, i.e an array, generic list, etc. You then check that collection for an instance of an object before retrieving it from the db. So when loading data from the db, you'd first check your Identity Map collection to see if you already have an instance of that object. If you do, you get the object from the collection. If you don't, you get it from the db, store it in the collection for future retrieval, and then return it.

    I would probably use a generic List<T> as a container for the business objects.

    Hope this helps,

    Paul


    Paul Delcogliano
    • Marked as answer by nebocreek Wednesday, May 18, 2011 3:36 PM
    Wednesday, May 18, 2011 12:24 PM

All replies

  • Jason,

    I think you're on the right track. There is a design pattern that could be useful to you. The pattern is called Identity Map. You can find a brief description here... http://www.martinfowler.com/eaaCatalog/identityMap.html

    The idea behind an Identity Map is to store all objects retrieved from the db in one collection, i.e an array, generic list, etc. You then check that collection for an instance of an object before retrieving it from the db. So when loading data from the db, you'd first check your Identity Map collection to see if you already have an instance of that object. If you do, you get the object from the collection. If you don't, you get it from the db, store it in the collection for future retrieval, and then return it.

    I would probably use a generic List<T> as a container for the business objects.

    Hope this helps,

    Paul


    Paul Delcogliano
    • Marked as answer by nebocreek Wednesday, May 18, 2011 3:36 PM
    Wednesday, May 18, 2011 12:24 PM
  • Paul,

    Thank you!  That was DEAD ON.  Your suggestion led me to a fantastic article by Jeremy Miller on Persistence Patterns that was EXACTLY what I needed:

    http://msdn.microsoft.com/en-us/magazine/dd569757.aspx#id0400073

    This article was mana from heaven for me.

    Thank you so much for your reply!  You've made my week!

    Best Regards,
    Jason

    Wednesday, May 18, 2011 3:35 PM