Objects and Databases
When you analyse a business domain, you are creating a conceptual model of that domain. You identify the entities in that domain, the state and behaviour of those entities, and their relationships. However, at some point, that conceptual model has to be translated into a concrete software implementation.
In fact, in almost all practical business applications, it has to be translated into (at least) two concrete software implementations: one implementation in terms of programming entities (objects), and one in terms of a relational database. This is where things start getting tedious and potentially complex, because the object and relational worlds use quite different representations.
At best, the code to query the database, load objects and save them again is laborious and repetitive. More often, there are additional complications, such as multiple types of objects with associations between them – for example, a Customer has a set of Orders – or inheritance relationships – for example, we have identified AudioClip and VideoClip as sharing a considerable amount of state and behaviour, and would like to model this using inheritance. The extremely different representations of associations and inheritance in the object and relational worlds makes it complicated as well as laborious to write code that translates between the two representations.
This is where object-relational mapping comes in. An object-relational mapper, or ORM, takes care of the mechanical details of translating between the worlds of programmatic objects and relational data. The ORM figures out how to load and save objects, using either explicit instructions such as an XML configuration file, or its own heuristics, or a combination of the two. This lets you, the programmer, focus on writing your business logic and application functionality against the domain model in its object representation, without having to worry about the details of the relational representation.
LightSpeed and Object-Relational Mapping
LightSpeed as an object-relational mapper leans strongly towards using its own heuristics to figure out how to load and save data: that is, it works out how objects and properties map to tables and columns without having to be told. This is known as convention over configuration. The immediate practical benefit of this is that we don’t need to write rules telling the ORM how to load and save objects. The impact is that it requires us to keep our object design and our database design reasonably in sync. However, even this has a higher-level benefit: it guides us towards a consistent data design that reflects the business domain.
What does this mean in practical terms? It means that when we identify a domain entity, we always have the same basic tasks to wire it up in LightSpeed:
· Create a class representing the domain entity.
· Declare properties representing the attributes of the new entity.
· Create associations to other entities.
· Create the underlying database schema.
Once we’ve defined our entity in this way, we can use LightSpeed to retrieve or persist instances of this entity to and from the database. We can also go on to configure behaviour (e.g. adding validation) and performance (e.g. caching or lazy-loading) as required, and to extend the domain model by adding custom methods.
LightSpeed provides a visual designer for creating domain models and defining domain entities. The designer makes it easy to produce both the object and relational representations from a single master model, providing an extremely convenient modelling workflow. You can also define entities purely in code.
For a step‑by‑step introduction to creating domain models and using them in LightSpeed, see the Getting Started guide, which you can find on the Start menu.