Which pattern should I use for my unique instance of the User class?

前端 未结 6 825
醉梦人生
醉梦人生 2021-01-14 18:51

I have this User class

class User{
  private    $logged = false;
  private    $id;

  public function User() {
      //> Check if the user is logged in wi         


        
6条回答
  •  野趣味
    野趣味 (楼主)
    2021-01-14 19:54

    It is always hard to answer architectural questions without the context. In this case it is pretty important how the User objects are persisted (where do they come from?) and how is the client code organized. I will assume a MVC architecture because it's trendy this days. Also I suppose your user objects will have more responsibility as only authentication (you mention some permission control here, but it's still not clear enough).

    I would push the authentication responsibility to a service and just pass it around as needed. Here is some sample code.

    class AuthenticationService {
        /**
         * @var User
         */
        private $currentUser;
    
        public function __construct(Request $request) {
            // check if the request has an user identity
            // create a user object or do nothing otherwise
        }
    
        public function getCurrentUser() {
            return $this->currentUser;
        }
    }
    
    class User {
        public function editPerms(){}
    }
    
    // the client code
    class Controller {
        private $auth;
    
        public function __construct(AuthenticationService $auth) {
            $this->auth = $auth;
        }
    
        public function handleRequest() {
            $currentUser = $this->auth->getCurrentUser();
    
            if ($currentUser === null) { // of course you could use Null Object Pattern
                // no user is logged in
            }
    
            // do something with the user object
        }
    }
    

    So the answer to your question is: you need proper dependency injection through out your whole application. The only object you get from the server is a request. The dependency injection container injects it into the AuthenticationService and the latter gets injected into your controller. No singletons, no static methods, no global variables. The dependencies are tracked in the DI container and are injected as needed. Also the DI container makes sure your service is instantiated only once.

    The article "Container-Managed Application Design, Prelude: Where does the Container Belong?" may clarify some DI concepts.

提交回复
热议问题