Functionality part 1 - Object Chaining

So I've described the thinking behind Norman as well as how my 'Not an ORM' can be seen like kind of an ORM.

I also make statements in the releases to the tune of  "Still no object chaining, persistence errors or remote server functionality." in the release notes, with a kind of implicit belief that someone will know what I'm talking about.

I can, however, forgive people for still being a bit confused about where it is going.

The three immediate goals I see for Norman are, as mentioned above, Object Chaining, Persistence Errors and Remoting the server. One component I would like to see, but it is a much further in the future, would be a DSL, possibly Microsoft DSL Tools or Oslo based, possibly not. I shall discuss all of these here and in future posts.

  • Object Chaining

One tenant of the design of Norman is 1 object, 1 data table. There is no concept of Table Joins when mapping an object to data. In concept, this is similar to the data model for microsoft Azure. If an object needs to be described over more than one table, it is probably too complex to be a single object.

As an example, we can take a look this model, where an object model was designed to build modelling software for business intelligence solutions.

Simple BI object model

As I have already stated, the report class here probably should represent an object hierarchy, but consider that the developer has decided to ignore the Single Responsibility Principle and decided to cram the entire report structure in a single class.

A report can be viewed as containing source data, pages, prompts, fields, charts and headers. Without getting too deep into how this class may be designed, we can immediately see that to represent this object in a database, we will need multiple 1 : many table joins.

If, however, we split the report class, in good OO principle, to an object hierarchy of loosely coupled classes, we may get something like the following.

We now have a collection of classes that can all be represented in single database tables. This may appear little more than good development technique, and certainly an uber-report class would be a horrible code smell, but understanding the concept is crucial.

Now, when building these classes, if we decorate them with metadata attributes to describe these relationships, any class can immediately describ its dependant classes.

One benefit of this is that when an report object (for example) is requested from the engine, a chain of dependant objects can now be derived, and lazy loaded into memory. This way, when the report is being persisted back to data, if another user has also changed that report and saved it back to the datastore, in the meantime, the local user has the entire chain of data required to describe the report as they see it, and the application can handle the inconsistency of the data being persisted with the data in the datastore. This will be handled by PersistenceErrors, which I shall describe in a later post.