Business Entities ... old story but new colors!

Published 10 November 05 11:15 PM
In this new project of mine, we are making sure that application architecture is very mature and has a very solid base.

Beside other problems, like always we had an debate during the process of finalizing how we will model our entities. One thing was obvious that we will be using DataSet. First debatable issue was the usage of typed dataset vs. un-typed. I am in favor of using typed dataset as they facilitate the process of development and assist in avoiding data type mismatch, which is very common issue in case of un-typed datasets. You have to perform type checks in business tier before sending data to persistence tier. And hence code size increases. If you do not perform these checks, you get exceptions from persistence tier. If you are using transactions, these exceptions are very expensive coz at least I do not tolerate the fact that your are rolling back your transaction because instead of sending integer, you are sending a string by mistake. Beside this, all schema is ready made, you don't need to call the persistence tier with -1 to have the schema made in the dataset. Anyway, the top argument given against usage of typed dataset was that what if schema is changed? And if application is deployed on different machines, we gotta update the entity model every where. The answer is simple. We are porting an existing application which has been deployed in many countries and is happily serving many clients. We do not expect data model change. And if there is any, then updating a single assemble across three or four machines is not a big issue. Second object was that since typed dataset is "typed", it decreases the abstraction level between different tiers. My reaction on this argument was "Doughhhhh!!!". What is abstraction? Abstraction is hiding internal details, NOT an interface. Un-typed datasets are dirty in a way that if you change your database schema, they are automatically updated (so far so good) but what about the client of that business tier? You are changing the contract schema of data exchange with out notifying? You can update the client code based upon the change but what if you forget to change somewhere deep inside your code? Your compiler will happily compile your code. No major break down. This type of "Abstraction" is gonna kick you when you are least expecting. On the other hand, if you are using typed dataset, they will instantly break the contract and your business client will refuse to compile. I think this is good thing. Abstraction works well in case of interfaces and remote calls. You "abstract" your implementation but not that "contract". Abstracting your implementation helps you in changing the other side without breaking your business clients. Like there is a function called "bool ProcessCreditCard()", you are currently writing logic to work with LinkPoint. But in future, without breaking your clients, you can change the provider (provided that interface remains same). But what if you think about returning "Approval Code" instead of "bool"? This is breaking down the contract. You gotta update your clients now. Abstracting this change is NOT recommended.

Anyway, after that there was another issue. People were thinking that Typed datasets will act as entities. Then there occurred a problem... consider a scenario, a Quotation contains Applicant, Applicant information, Vehicle and Vehicle information. Similarly a Proposal contains Applicant, Applicant information, Vehicle and Vehicle information. Now question from the guy responsible for generating entities was that where should he place Applicant information? In Quotation or Vehicle XSD? Long story short, after discuss we agreed that we will define XSDs based upon subject areas. They will just be containers of data - not entities. We will model our entities like...

Quotation <Entity Object>
     - contains DataTable <of type Applicant> called Applicant
     - contains DataTable <of type Vehicle> called Vehicle
     - Expose DataRow <of type Quotation> called Quotation [or optionally will build set of attributes (in form of properties) around this single row]

     - A Method <Insert> ... will declare a DataSet, put all the tables in this entity into it and will pass to persistence to persist changes.
     - ....

If I need to to reuse Quotation some where, instead of defining Quotation information all over again, either I will inherit from this class or will Compose an object.

Now some words about insert method, our persistence tier contains one-one mapping against our database. One data access component against one table. We pass the dataset to the parent persistence object and after inserting itself, it passes the dataset to its junior. So in one call we persist all the changes.

Bottom line is, we are using kind of hybrid approach. Our entities are two faced. They have got kind-of OOP face for presentation tier (and others as well) and got dataset face for persistence.

Any comments / suggestions?

by fahad
Filed under:
Anonymous comments are disabled