I'll start with a little story. We had an object authorized user ( User
), and null
. And we always checked
if (!$user)
But there was a problem, for an unauthorized user there were about 5 default values and they always had to be dragged out and it turned out that instead of transferring the 1st object with data, it was necessary in any case to pass N parameters, or those received from a User
object, either taken from constants.
And then we decided to use NullObject (Guest
) and selected the interface from User
'a, called UserInterface
. And we added the UserInterface::isAuth
to check if the User is authorized. And we began to receive from the service not User|null
, but always UserInterface
and everything UserInterface
out, began to transmit the object everywhere and never check for null
, but a new attack came ...
Methods for which there was no difference whether the user was authorized or not accepted the UserInterface
and were happy, but those who had a difference accepted the object of type User
. And there is a small problem, because after checking the UserInterface
object on isAuth
, it does not become a User
object and the IDE swears, saying that the method accepts a User
object, and we only give it UserInterace
. And somehow it is not very nice. Although everything works fine, because if the isAuth
method returns true
, then this indirectly means that this object is of type User
.
How to solve this problem? Where were we wrong? Maybe we incorrectly solved this problem?
One of the solutions is to make an additional method in the Users receiving service, which will return User
or null
, and it turns out that we returned to what we started, but in smaller sizes ...
UserInterface
interface, if methods still acceptUser
? - Dmitriy SimushevUserInterface
, then program based on interfaces, not implementations. - Dmitriy SimushevUserInterface
interface, then any implementation of it can be used as a user object. Your architecture breaks the principle of encapsulation. - Dmitriy Simushev