4

Going by the general principle of data abstraction, I normally abstract data in a serialized format(JSON) and pass it as a parameter to the Business Logic(BL) modules such that the BL module always see a consistent format of the data irrespective of the underlying data storage layer. Even if I use a ORM, I use the serialized format of that ORM. I feel I have the following advantages.

  • By serializing data, there would be better control over data and parameters
  • Any developer can write BL without thinking too much about the underlying data storage
  • Wrappers can be written for new databases (There are a lot of ready-made wrappers to convert data into JSON)
  • Testing could be done ruthlessly and without a database (since the data format is serialized)
  • Functionally easier to understand and better OLAP, OLTP integration

I also notice the following drawbacks

  • A new layer to be added between the database and the BL module (most ORM's nowadays come with a predetermined JSON format)
  • Extra function calls slow down the application (but I think this trade-off is OK when compared to better testing and easy maintenance)
  • Increased level of abstractions may confuse the developer

I make the above observations mostly in the context of business applications To follow this discussion, lets have an example so that things could be discussed in its context. Assume a product database having the columns: Product,Rate,Taxes and we need to create a invoice

Code without database abstraction

GET rate,taxes for product X from database
multiply qty with rate and add taxes
display invoice

Code with database abstraction

  GET rate,taxes for product X from database
  Convert it into JSON
  call create_invoice function //This does all the calculations
  display invoice

In the second example, I would pass arguments in the form (Product=X, Qty=5, Rate=5, Taxes=0.05). If taxes are to be split into more that one category (State Tax=0.03, Central Tax=0.02) or a discount factor to be added I would just increase the number of parameters in the BL functions such that the database fields, the JSON keys and the function parameters match (this is done automatically during serialization and most ORM's do it). This makes it easy, in my approach, to extend functions and also make modules independent of data since the modules always know the data they can receive and even if they receive a new parameter, they can adapt it provide the underlying code is intelligent.

My general questions are

  1. Is this a good pattern and what's it called (Data abstraction comes to my mind)?
  2. Pros/Cons of this pattern(apart from those mentioned above) in the context of business application, apps for embedded devices, big data
  3. Is there a difference between this pattern and ORM (I believe so since ORM is mostly a class wrapper to get data from a database while this pattern is more oriented towards data structure)
  4. If this is good, can this be easily understood by a new developer?

3 Answers 3

3

A lot depends on your intention. Data serialization in this manner just to pass on to the business logic of a single application, seems wasteful, when you should be passing a native object from the ORM to the object encapsulating BL which will modify state and return the object to the ORM for persistence.

On the other hand, if you have multiple, distributed applications that handle different aspects of of the domain, then wrapping your DB in an API to provide serialized (JSON or XML) data is a good idea.

For instance: I have to deal with a rather insane vendor-supplied legacy database in which a major constraint is inability to modify the DB schema other than adding the occasional view. I have this DB (as well as a couple of our other 'enterprise' data stores) wrapped in a REST API. Most of our user-facing applications, as well as daemons that monitor the DB for certain events, communicate with the API. In this way I can have the following workflow:

  1. OR/M classes each wrap a single table in the DB. One object == one record.
  2. Decorator classes handle presentation, including composition of more complex objects from simple model objects.
  3. Controller classes respond to requests with a JSON representation of the object appropriate to the client application.
  4. Clent processes data, POSTs or PUTs JSON object back to the API
  5. Controller requests to save object, which is decomposed back to model objects and persisted by the O/RM.

This adds significant complexity.

If you have to deal with heterogeneous data stores, distributed applications, etc., this is an excellent solution. But unless you have those requirements, the rule of thumb is You Ain't Gonna Need It.

3
  • You are spot on. I mostly work on a variety of databases and data structures (since most of my work deals with analysis and reporting), and since most of my business logic is same, I have started using JSON as the standard input data format.
    – Ubermensch
    Jan 13, 2012 at 15:31
  • JSON is a dream. We used to have to use XML for this stuff. I still wouldn't store JSON in the database as JSON in most cases. However, I'd use it to serialize records read from the DB. But as a data interchange format, JSON is fantastic. Jan 13, 2012 at 18:11
  • But most of my job deals with analysis of records from databases and providing a nifty interface but for the first time I got to save records into a new database that could be used as is with simulation. Since ACID is unimportant here, I decided to extend the serialization into MongoDB and use Python to write the business logic. Performance isn't going to be a problem anytime soon. I believe this as a good strategy from the functional point of view. And if performance issues arise in the future, extensions could be written in C so that the performance part is isolated from functionality
    – Ubermensch
    Jan 14, 2012 at 4:13
2

Databases already provide a standard format for their responses and database drivers already know how to interpret/use them. The JSON marshalling and unmarschalling steps are therefore superfluous if the result in its format won't be transferred to another system.

In my opinion you should move more towards encapsulation, with native objects and structures instead of passing a serialized data fragment around.

The only advantage I see is the testing process; you can inject methods with random JSON data and don't need a database. But that's kind of a big trade-off for so much perfomance-loss.

2

Usually, i work in languages/environment which is are closer to systems compared to example here so my answer could be slightly biased. However, there is an interesting concept/pattern i have found with many good designers.

Usually, in order to foster the code to be reused - certain things needs to be generalized. Classic examples of generalization are text books examples of inheritance; and one realize that once a generic API for a class of objects it helps evolve systems. We all know that it is good to abstract out common versus specific functionality in such manner.

However, i have seen this with many designers that sometimes they try and do super generalization. One of the example i saw is a a classic C++ application. Instead of generalizing by keeping most common parameters specific to an abstract(virtual) function, the code does super generalization by passing parameters as arbitrary list of name-value-pairs. Now any function/method can be generalized trivially if all relevant arguments/parameters are serialized and passed to function and de-serialized in processing it.

But such a super generalization is very bad. Not only that it adds overhead of adding serialization/deserialization process -but more importantly the semantics are lost. Now the callee function can put in arbitrary parameters and the whole thing begins to get misused way beyond context. You also run into un-handled, misspelled parameters, out-of-context parameters and so on; all this because there is no way to control what sort of parameters can go in.

As a thumb rule, i would always be worried of super generalizations and be rather simple.

NOTE: The pattern you described above is NOT ORM. In ORM, you generally treat a DB record with equivalent Object which has same attribute. The JSON based representation still requires translation to native object before use.

1
  • Thanks for your remarks on super generalization. The main reason for me using JSON is to get interoperability between different databases and structures(since most of my work deals with analyzing business data). Also, does converting JSON into a native object could be a good option (in case most of the data is in a nested structure). I want to have data and metadata in the same entity (By data I mean the business data and by metadata I mean the rules to be applied to this data to get the output, similar to a rules-based engine)
    – Ubermensch
    Jan 12, 2012 at 4:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.