![]() |
Development Lifecycle »
Design and Architecture »
Design Patterns
Intermediate
The Entity Design PatternBy Matt GullettA design pattern for logically representing data and decoupling the persistance of data from the application view of that data. |
C++/CLI, Windows, .NET, Visual Studio, Architect, Dev
|
|
Advanced Search Add to IE Search |
|
|
|
||||||||||||||||
Define a representation of data that facilitates a separation of physical and logical views of the data and its supporting metadata constructs.
A common programming requirement is to load raw data from a physical data store such as a database, XML file, etc and to provide a "view" of the data that is logical to an application's needs. This logical view of the data will often include certain metadata such as possible values or ranges which can be applied to a particular part of the data. It is not desirable to always implement each logical view of the data as its own class (or set of classes), because this promotes code duplication. In addition, it is often not desirable for various portions of an application to share a single logical view because this promotes overly complex designs which become tightly coupled with the implementation.
Consider a contact management application. In such an application, there is a need to store and display information that may include names, addresses, phone numbers and any other desirable data field. This information is typically stored in some form of RDBMS and accessed using the SQL language. Typically when working with RDBMS software, it is necessary and desirable to structure the storage of data into various tables, and implement integrity constraints accordingly. This process of normalization is intended to improve insert/update performance and reduce redundancy. Unfortunately, this process usually results in the logical view of the data becoming further separated from the physical, requiring the application to "map" the physical structure into a more meaningful view. This mapping process may be very simple, but can become quite complicated, when the separation increases.
In addition to the mapping of raw data, a contact management application will need to maintain certain metadata. An example of this meta data is apparent when working with the "Name prefix" portion of the data. A name prefix will typically be one of a set of values such as Mr., Mrs., Ms., Miss., etc. This list of values will need to be available to various portions of the application, to facilitate user-interface specific functionality and to provide validation support. Different portions of the raw data will have varying metadata associated with it. Metadata can include value lists, validation rules, application specific properties, etc.
We can solve this problem by designing a basic "Entity" class that encapsulates the raw data, and binds the associated meta data to it and provides a common interface for accessing and manipulating the raw data. This Entity class will hide the specifics of data persistence from the rest of the application and provide a basis for many data-centric controls. The ability to implement data-centric functionality, decouples the data from the application and facilitates code reuse.
An added benefit of the Entity pattern is the ability to define multiple logical views of a single physical representation of data. This ability can be critical to applications requiring a high level of security or customization.
Use the Entity pattern when
the physical representation of data diverges from the logical representation desired for an application.
there is a need for more than one logical representation of the same physical representation.
the physical representation of data is subject to change, while the logical view remains consistent. This often happens when there is a need to persist data to or from disparate physical formats.
more than one data set needs to share a common set of functionality.
there is an extensive amount of metadata associated with the view of the data.
there is a need for transactional behavior within the logical view of the data.
Sorry guys, I don't have a good way to draw the structure for this, though I wish I did. So, let me describe it with as few words as possible.
The Entity pattern has the following benefits and liabilities:
Here are some useful techniques for implementing the Entity pattern.
Implement a generic base class to represent behaviors and actions which can be taken based on the logical view of the data. The derived classes could potentially be implemented as generics, to further improve robustness and flexibility.
An example of an action which can be applied across all Entity objects regardless of the logical views, is an integrity checker. An integrity checker could interrogate the Entity object for all fields contained within it, execute the appropriate validation rules and report any inconsistencies.
An additional example of a generic action might be a DocumentWriter class. This class would be responsible for interrogating the Entity object's logical view and producing a document (in HTML, PDF or any other format), which details the structure of the entity, the fields, value lists, rules and any domain-specific properties contained with it.
There are literally hundreds of possible ways to use the self-documenting nature of entity objects, to produce flexible and reusable data driven behaviors. These behaviors could be used as needed, by any application, component, or user, without concern for the actual data being acted upon. Domain-specific properties can be applied to the entity, to further customize these behaviors.
Implement support for instrumentation at the data level. All access to the raw data and metadata must pass through the Entity class. Instrumentation of this access can be easily localized to the Entity object.
It may be desirable to log the data that is accessed, who accesses it and when they access it. Doing so with this pattern is quite easy because all of the data access passes through a common base class.
Implement support for dynamic run-time customization of logical views. In our contact management application, it is often desirable to allow a user to add (at runtime) custom fields to the contact data objects. The Entity class should facilitate this runtime configuration through its exposed interface and provide a means for insuring that the customized field is properly dealt with throughout the application.
The custom fields should behave like all other fields. A property may be set to indicate that the field is user defined. However, in all other respects, the field behaves exactly the same.
When this feature is present, it is more important that the StorageEngine classes be implemented as discussed earlier. It is not possible to rewrite the persistence code whenever a user needs to add a custom field. If the storage engines are designed to interpret the logical view at run-time and automatically cope with the underlying physical view, then the application should be able to continue without interruption.
Implement support for calculated fields. Most data sets include static and calculated field values. For example, a contact Entity may have a field named DOB to represent the date-of-birth of the contact. It would be redundant and unwise to also include a field named AGE to represent the age of the contact, because the age can be computed on-demand based on the date of birth. Instead, the AGE field should be included in the logical view as a calculated field.
Calculated fields should behave exactly the same as normal fields. The only significant difference may be that they are read-only and that they are typically not persisted to physical storage.
Here are some additional concepts which can be applied to this design pattern.
None provided at this time. A future article may provide a full implementation of this design pattern.
General
News
Question
Answer
Joke
Rant
Admin
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 8 Jun 2003 Editor: Smitha Vijayan |
Copyright 2003 by Matt Gullett Everything else Copyright © CodeProject, 1999-2009 Web22 | Advertise on the Code Project |