Programmers are notoriously stricken with pride when it comes to the design and coding of a solution. Inevitably, each developer will believe that their particular approach is a) right, b) best, and c) unworthy of scrutiny. I certainly am guilty of this kind of thinking.
Thus, often established patterns or best practices fly in the face of the individual developer’s “I know best” mentality. We rationalize our approach, and invent reasons why it’s better than the industry adopted standard or recognized method. Consequently, we miss out on the benefit of the collective skills, experience and talent of the larger development community, and our products suffer from the unsupportability of highly idiosyncratic code.
I use this preface to provide context to the following rant about a trend often seen in .NET development: using DataSets as business domain objects.
Object oriented programming has its strength in being able to accurately describe an piece of the world in a way that is predictable and reliable. More recently, the separation of an object definition (that is, its properties) and object manipulation (that is, methods that operate on an object) has brought forth the trend to have distinctly define domain classes.
A DataSet, while a suitable container for values pulled from a database table, is not a distinctly defined domain class. It lacks structure, strong typing, and predictability. Yet, it is an easy shortcut to connecting our application data to a set of business rules.
Here are my objections to using DataSets in the place of Domain Objects:
1. They are unpredictable.
Since a DataSet is based on the results of a query, it may at any point in time contain different fields even though it is named the same. For instance, if two different stored procedures are used to retrieve a Customer record, but one has more (or less) fields selected, then I as a consumer of that data cannot reliably know what fields are available to me. Does the query return First Name and Last Name, or does it concatenate them together as Full Name? I don’t know until I try to reference a field that doesn’t exist.
Contrasted with a Domain Object that explicitely defines the values for a business entity, such that I can always know what values are available to read or write, a DataSet inevitably leads to exception based development.
2. They are not strongly typed.
When I define a Domain Object, I explicitly declare each field and its data type. If I try to assign a value that doesn’t match, I get an exception. There is an intrinsic level of control that accompanies the strong typing of a well written Domain object. A DataSet, however, is not explicitly typed.
3. They are undocumented.
In writing a Domain object class, at least with .NET, I have the opportunity to annotate my properties with API style documentation that will be immediately available to any consumer of that class via the Visual Studio IDE. I can tell my fellow developers about any nuances or rules affecting that class. Further, the Visual Studio Intellisense auto-completion mechanism will allow a developer to see all of the properties available for that object.
A DataSet is a dumb container. When I ask for a value from the DataSet, it gives me no context, guidance or insight to what that value is or represents.
To be fair, a DataSet is certainly useful for in-memory representations of data. But they fall flat when it comes to accurately modeling a domain or representing an entity.
Here is some additional commentary on this topic from people far more qualified to expound on the details of this discussion.