I have a baseClass
where I do not want public setters. I have a load($id)
method that will retrieve the data for that object from the db.
I have been using static class methods like getBy($property,$values)
to return multiple class objects using a single database call. But some people say that static methods are not OOP.
So now I’m trying to create a baseClassCollection
that can do the same thing. But it can’t, because it cannot access protected setters. I don’t want everyone to be able to set the object’s data. But it seems that it is an all-or-nothing proposition. I cannot give just the collection class access to the setters.
I’ve seen a solution using debug_backtrace()
but that seems inelegant. I’m moving toward just making the setters public.
Are there any other solutions? Or should I even be looking for other solutions?
2
Your Domain class (let’s say a Book class) loads itself from the DB?
I’d rather avoid that, because this way you mix up the domain model with persistence code.
However, to your question: what I’ve seen in some frameworks in Java is that they define a public interface (in your case defining getters), and the implementation class has only, let’s say, package accessibility. The receiver of the instance sees only the interface and thus can only access the getters, while the creator has full control over it. This requires to have different packages with different visibility, which is probably hard to maintain.
Another way could be (if you are not developing a framework) to make the setters public, but define a general design rule like “Setters may be used by DAOs only”. It must be possible to define and communicate such a simple rule to your team to make it work on a long term.
2
-
Static methods aren’t automatically non-OOP. If they improve encapsulation or reuse value, they’re probably fine. In general, the interface to a class includes all the routines that work together to carry out that class’s work, even if they are static or non-member. Scott Myers wrote a DDJ article on non-members, for example.
-
Different languages have different levels of support for access restrictions. In C++, you could use the named constructor idiom, but make the static construction members (e.g.,
static baseClass newClass(...)
) private. Then no one can create instances ofbaseClass
. Then make thebaseClassCollection
afriend
ofbaseClass
andbaseClassCollection
will be able to createbaseClass
instances from the database using the named constructor.
2