A program I'm currently designing makes heavy use of the database, almost anything the user does will alter the database, or read from it. Now I have one interface which defines all these operations, and one database class which implements it.
The result is that that class is huge, it contains logic for creating users, editing them, creating events, showing events to the user, editing, adding friends, adding items to a product, ....
On the one hand I can argue this does not violate SRP, because the whole use is database communication. On the other hand, this is a lot of code for one class.
Are there any design patterns that solve this, or is this acceptable?
-
If this is the case, and the user experience could be damaged as a result, you should consider using an in-memory database (Couchbase, for example) to mitigate the delay caused by r/w operations.theMayer– theMayer2014年11月28日 15:06:10 +00:00Commented Nov 28, 2014 at 15:06
2 Answers 2
Yes, I think you are violating the SRP. Not because you kept all of your database code in one class, but because you have database code for completely different entities (users, products, events, friends) all in one class. At the very least, separate your code into classes by the entity it's most closely related to. If you're looking for design patterns, you might want to read about the Data Access Object pattern as a place to start.
If your application really is sooooo "database heavy", it's also worth considering that some of your logic could be moved out of your application's code and into stored procedures/functions within your database. That would make your application's code a little more manageable, but you would have to maintain code in two different places.
On the one hand I can argue this does not violate SRP, because the whole use is database communication.
You could also say you have a single class in your application, because the whole class does processing of data.
It doesn't work like this. If your class has:
- a mix of different abstraction levels;
- a mix of things that can be described as separated by "and" (your class manages users and items of a product and events etc);
- things that are modified for different reasons;
then you should split along those lines.
It may be still acceptable to keep everything in a single class, but then the class' role should be "provide single access point for all DB operations".
In that case, your class should be an extremely thin class, simply forwarding calls to various sub-components and not needing alterations when (for example) the data model for users changes.
From my list above, you can extract one or (preferably) more refactoring guidelines:
- split by abstraction level / operation type / DB query type
- split by entity type (user data model, product data model, etc)
- split by categorizing data models (user management tables and operations, products - and their subitems, prices, offers, etc)
-
I will be using the facade pattern to provide a single point of access :)Dylan Meeus– Dylan Meeus2014年11月28日 14:02:56 +00:00Commented Nov 28, 2014 at 14:02