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 ...

  • one
    Let them accept a UserInterface that has an isAuthorized () method. And even better is to completely separate the logic of working with the user and with his rights, and transfer different objects in general (the object representing the user and the authorization context ). - etki
  • @Etki can be accepted, but then it will have to be checked everywhere on isAuthorized, and by passing and waiting like User, verification is not needed (but I agree that this will solve our problem). As for the rights, we don’t have them, there is only an unauthorized user and an authorized user. For an authorized user, an account is available and that's the whole difference. And the authorization context in our case is redundant. - AmsTaFFix
  • And why did you then define the UserInterface interface, if methods still accept User ? - Dmitriy Simushev
  • one
    Why such crutches ?! Once you enter a UserInterface , then program based on interfaces, not implementations. - Dmitriy Simushev
  • one
    Something tells me that your user logic is poorly designed. If you define the UserInterface interface, then any implementation of it can be used as a user object. Your architecture breaks the principle of encapsulation. - Dmitriy Simushev

0