Background
This question stems out of an architectural discussion we had at work.
For the current project we are using Python and an object oriented database. There are input services that we consume, and certain interfaces that we are expected to provide output through.
Someone on our team started designing a data model, and my question was: why?
A data-only object in Python can just as well be be represented by a dict (there is a fair amount of questions about that on this site). We don’t have a relational database that has columns that we need to map objects to either. At the same time, there is a cost to a data model in that it will always need to be maintained. When interfaces change it (IMHO) simply becomes another dependency that needs to be satisfied, but unlike in static-typed languages it does not actually enforce anything.
Question:
The way it seems to me is that when you are in an environment where everything is dynamic, it makes sense for the interfaces to define your data model implicitly rather than maintain some sort of classes that define a model. Are there ever any good reasons to the contrary?
EDIT
In the comments and answers people seem to be focusing on two areas, they are: database mapping and representation as well as validation of the data model.
I apologize for not being more explicit about the DB, but in this environment that we face we have an object-oriented DB that stores blobs in a file system-like representation. There is no mapping to SQL and no ORM of any sort to speak of. I do understand the argument though. For example, Django’s models require subclassing for ORM to work. In thise case, making model classes makes perfect sense because the DB is effectively a static-typed data store and not ‘dynamic’. But this is not the scenario of the question, because it’s not a pure dynamically typed environment.
Regarding validators: yes. One will need to create validators that check fields being present, and them being of the right type. In static-typed languages the model implicitly does this (when you’re coding C++/Java you can’t stick user ‘std::string’ to where a User class should be). But in Python, a model class does not enforce anything. If I am building validators that check presence of attributes anyway, does this not make classes, dicts, generators etc functionally interchangable? And if so, should the solution not be one with least code? Validators in general seem to me to be an argument in favour of not building data model classes rather than the contrary. Am I wrong in this?
9
Even in a dynamic language the principles of Domain Driven Design can still apply. If all you’re doing is passing around dictionaries, you have an Anemic model where your objects are pure data and other objects operate on them.
Taking the time to create a rich object model and embedding logic into the model provides an opportunity for your model to be more expressive and representative of the domain you’re modeling.
5
When I worked against Mongo we got dictionaries back. In some parts of the code we converted it to an actual object. In other places we kept it a dictionary. In most cases, the objects were just for convenience so we could say customer.name
instead of customer["name"]
. In these cases we used a dotted dictionary (a class overriding __getattr__
).
There were cases when the domain model “viewed” the data differently. In these cases we created objects with the structure we wanted and mapped our data objects to them. It can make a huge difference in readability to do this mapping once up-front rather than scattered all throughout your code.
Another place where an actual object was useful was when validating schema. There are some Mongo wrappers out there that will allow you to define checks when grabbing and storing documents. This is useful for keeping your “schema” consistent in the face of user error. They can provide default values for missing attributes, convert dates into strings and things of that nature. There are similar libraries for working with JSON returned from a web application.
2