Should search/get methods that retrieve rows from a database be instance methods or static methods?

74 views Asked by At

Why would I want to make all my search/get functions that retrieve rows from a database, instance methods? If I have a getByID(id) or a findPeople(person attributes) function, that either returns object(s) or throws an exception, what justification is there for the overhead of creating an instance of this class every time I want to call one of these methods?

I've heard it makes things more testable, but in this case I don't see why -- the instance methods don't really interact with the other properties of the class at all.

2

There are 2 answers

0
ircmaxell On BEST ANSWER

Well, the question is, how do you want it to work... There are a few patterns built around this concept.

If you want to get one:

If you have many similar things (like types of people), then you might want an Abstract Factory. In that case, you'd likely not want it to be static. But then again, you'd want an instance so you can bind your individual factories to the abstract factory. That way, you'd pass around a "Person Builder" factory. Then, when you're looking up an individual, you'd call builder.buildPerson(id). That method would look up the individual, and determine the class to actually instantiate, and call the respective factory.

If there's only one type of "person", then I'd use a Factory method. In that case, since the class (and its children) are responsible for instantiation, static methods are the preferred way. So you'd then call person::getPerson(id).

If you want to get many:

If you want to get many people (Such as with a findPeople method), then the ultimate solution would likely be dependent upon your need.

If you need some kind of efficiency with object creation, then you're likely looking for a Flyweight pattern.

Otherwise, if you're using an abstract factory, then make an instance method to find multiple based upon attributes. If you're using a factory method, then add another static method to find them.

But another way of looking at it

Is that "storing" and "loading" of the data for an object is not related to the object itself, so it does not belong as a method (static or not). In that case, it would be better to have a model that represents the datastore. Then, to get a list of users, you'd call peoplemodel.getPerson(id). The peoplemodel would fetch against the DB, and load the information necessary to construct the object(s). Then, it would call the factory on the person class to construct the actual object, and return it.

This is nice, because it's separating the storage from the implementation. Sure, it's another layer, but the extra layer lets you do things like have multiple datastores, or use the same person class for multiple applications with different storage requirements (since all the class cares about is the data passed in).

So, in conclusion:

Now, you can't achieve loose coupling of separate components via static methods, so in this case you'd need to use instances on both sides. So you'd pass in a builder to the model (dependency injection) to create the people objects. And since the model itself is loose-coupled, you'd get an instance of that and pass it where you need to load people.

So in short, it depends on what you're trying to do. But if you want the loosest coupled code (most reusable and most maintainable), then stay away from static methods and stick to abstract factories/builders and DI...

0
Gabriel Ščerbák On

Generally from the OO design standpoint, static methods are considered to be bad, bacause you loose all the polymorphism benefits etc. The other reason might be to reuse already retrieved information, e.g. once you select a set of objects and then you want a subset, you dont need to go into DB, or you can create more specific selects (you don't have to manually duplicate the first query, which might have been complex). You can also use instances as futures or builders, so you can evaluate your query as needed and carry it in an instance in the meantime.