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 ...
UserInterfaceinterface, if methods still acceptUser? - Dmitriy SimushevUserInterface, then program based on interfaces, not implementations. - Dmitriy SimushevUserInterfaceinterface, then any implementation of it can be used as a user object. Your architecture breaks the principle of encapsulation. - Dmitriy Simushev