user1156544
user1156544

Reputation: 1807

Avoid large classes for interface implementation

I have always tried to follow the advise by Mr. Martin and others of keeping my classes small. Very small, having only one reason to change a class. But now I am facing a dilemma where I do not think this will be that convenient.

I have an interface for GenericDatabases. This interface defines all methods that any implementation has to implement (e.g. getUsers, getUser(id), etc), perhaps 30 or 40 of them.

This way is very convenient, since a class only has to implement that interface and the code will work seamless with different specific databases. However, the problem is that such implementations can get +7000 lines long (god class).

What I have normally done in the past, is to divide the database functionality in different classes according to the objects they managed. But it was only for one fixed database implementation. Now, I could divide the functionality into different interfaces according to the database objects (users, documents, etc) but then it seems more burden to maintain. First, I cannot assure that a database implementation implements all interfaces. Then, developers are required to create perhaps 20 different classes implementing 20 different interfaces, where before everything could be found in a single class implementing a single interface. So I am not sure if this is an exception to the rule of always keep your classes small.

How can this class/design be refactored?

Upvotes: 5

Views: 648

Answers (2)

GhostCat
GhostCat

Reputation: 140437

Keep in mind, the ground rule is: you always prefer a complex network of simple things over a simple network of complex things.

The point is: as soon as interfaces (and therefore implementing classes) get too large, they (almost automatically) violate the Single Responsibility Principle. And sooner or later (rather: sooner) that means that instead of small, "understandable" units you end up with those large classes that are simply "too large".

Again: the main motivation for preferring smaller classes is the fact that your brain is much better at understanding "the whole thing" when that "whole thing" is small enough to "fit" into your brain.

So, yes - that might mean that you come up with a series of interfaces. And more classes implementing them. Complexity is like water: you can't compress it - you can only choose how it "flows".

Beyond that, Domain Driven Design might have some good advise here as well - for example regarding the fact that not all methods belong on an Entity - sometimes it makes much more sense to have Service classes that are responsible for "doing something" with an entity (instead of having the entity implement that method itself).

Given the comment by the OP: one has to understand that it is hard to give specific advice on such "generic" input. In order to really come up with helpful interfaces (that make more sense on their own, enough sense to "make up" for the cost of having many interfaces) one has to sit down and see the real requirements. Meaning: it is not possible to give more specific advice at this point. This is something that can only be resolved by the OP (and his peer) sitting together and carefully making experiments to figure which design options best fits their needs.

Upvotes: 5

Alex Favieres
Alex Favieres

Reputation: 1

Keep your class small is just a recipe to try to avoid giving more than one responsibility to a class. The problem I see is that your interface is trying to do too many things.

If you are working with a separate layer for the bussiness I suggest you look into the Repository pattern. Every concept of the model has a small number of methods he cares for and that is the interface he is linked to. Each interface could have one or more implementations that are not so big. Maybe, some of them could inherit or cooperate with a Database Helper that has little responsibility (create a connection, create a prepared statement and little more).

Upvotes: 0

Related Questions