0

I'm hoping for a sanity check in my design thinking.

I'm working with a small team on a website based on a MongoDB database. There are several collections in the DB -- for example, one representing persons, and one representing polls. Persons vote in polls, and their votes are recorded in a votes array in each poll, as a document with the person's id number and the vote they cast (e.g. yes or no). Persons have information about location and other profile info.

All the code is in Python. For purposes of extracting data from the DB for an API and for web display, I'm thinking about making a Person class and a Poll class. Each of these would have methods to get data from the other collections.

For example, a Person would have Person.get_polls() or Person.get_votes() which would go to the other collection and retrieve all the polls a person had participated in, and find the votes they cast in each one. Likewise, a Poll would have Poll.get_persons() which would return the list of person data from the Persons collection for everyone who'd voted in that poll.

Every time a developer wants a feature to get polls or persons, they'd go through this class system, rather than accessing the database directly with pymongo queries, because the queries would be built into the classes.

Is this a standard approach? Does this promote flexibility because we can change our database easily by just changing the method implementations once? Or does it reduce flexibility because it ties everything to using those classes?

1

Basically, you're saying you want a more object-oriented interface to the underlying database. For RDBMS, this piece of software is called an Object Relational Mapper and is hugely complex, but necessary(?) for large systems. For MongoDB in Python, there's MongoEngine. As with any tool, you should evaluate it and determine if it suits your needs. If your application is small, it's possible that a third-party library is overkill, and you can write a simple collection of utility functions and classes.

Most importantly, you should discuss with the other members of your team as well. Maybe they're perfectly happy writing JSON queries.

-2

Each of these [collections] would have methods to get data from the other collections.

No! This is inappropriate dependency coupling.

Well, of course client code has to be able to use another class. First, a (Person) collection is just a collection (repeat as needed). To do something with it there should be a "polling functionality" class. This class calls the various collections' getters, because it alone knows what collections and parts thereof it needs for doing its polling/voting functions.

Will you have "get_persons" methods? Sure, but taking filtering arguments so that the API is appropriately general purpose, and does not assume the specific purpose of the call.


Persons have information about location and other profile info.

Certainly. But... Persons class should not assume any particular functionality or use for that information. Persons class will know what "equals" means or how to compare itself to another Persons object so that a Persons collection might sort itself. It might emit data in a particular format. But it should not know what customized aggregation with other classes is needed for "polling functionality"


Every time a developer wants a feature to get polls or persons, they'd go through this class system, rather than accessing the database directly

Yes.

First, the business layer is more loosely coupled to the data source. A lot of access to the database w/in one class is looser coupling than being spread across many classes.

Second, clients can assume valid state; that's what constructors are for. And collections can maintain valid state like not allowing duplicates, controlling mutability, etc.

Third, the client, "polling functionality", and business logic in general, should function independently from UI and data store.

  • down votes, plural? Elucidation will be helpful for those seeking a good-er answer. – radarbob Oct 7 '16 at 2:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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