If the title of this post gets you worked up, you probably shouldn’t read on. I’m about to bash your beloved DataSet.
Scott Mitchell has written more on why to avoid DataSets. While he touches on performance and the mechanics of what it does, I believe the issue is bigger.
Everyone can argue and compare performance numbers in different scenarios to justify one versus the other. The real argument, I think, is design. No matter what you do, your application must perform well enough to meet the customer’s expectations. The customer doesn’t care about the internal workings. So what other motivations do we have?
What about OO design. What about an object owning state and all behavior that goes with that state? A DataSet cannot substitute for a domain object. It has no custom behavior. It holds records. As long as DataSets are pulled and bound to the UI, the application will be of Procedural nature. I’m coming from a stand-point where I care about OO and the maintainability and testability gains associated with it, so DataSets don’t hold much weight with me.
Now we are talking about another issue altogether. Are you dragging and dropping a RAD application that will have a short lifespan (because RAD and Maintainability are antonyms)? If so, you can stop reading now because this discussion has no bearing on your application.
If your intention is to develop a well-factored object-oriented system with loose coupling between layers and high class cohesion, then please read on. You will want to identify entities in your system and develop your domain object first, NOT your database schema. If you start with the database schema first, you are starting with a handicap that is often hard to overcome. Start with your domain objects first and define the entities that your system will manage. Each of these entities will own some state and will encapsulate this state with custom behavior through their methods. One example is that if you have a Product object and you try to set the Price field to a negative number, the object shouldn’t allow it. The object is responsible for protecting its state. If you have a dumb data container (DataSet) floating around, then you have to jerry-rig some validating logic before you “Update” the changes back to the database.
If you have a well-factored OO design, you will always be able to extend the system with new functionality as well as change existing functionality with minimal impact. This can exist because each small responsibility is housed in its own object and not shared among the logical layers.
I really don’t care about convincing DataSet users to enroll in Rehab (unless they are on my team – which they aren’t). Good design isn’t easy, but the benefits are worth the effort. DataSets are easy. Speaking of easy. . . here are some other things that are easy:
- Maxing out your credit card
- Not paying your bills
- Sleeping in
- Settling for mediocrity
- Posting an nonobjective comment to this blog post
For the record, I have used a DataSet (and a strongly-typed one), but not any more.
I must say that the use of a DataSet object in an application doesn’t condemn it’s design to the lake of fire, but relying on that as your _business object_ does. If there is a situation where the overhead is acceptable, use it _inside_ your business object or somewhere else, but protect your entities. Don’t pass around naked entities in a DataSet exposed to the world. Use encapsulation. Protect your data.
Perhaps my main beef is with the use of DataSets as promoted by the VS.Net drag and drop tools.