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

前端 未结 6 827
醉梦人生
醉梦人生 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:31

    1. since everyone else is weighing in on this, singletons are not evil. i even read the "liars" article, and he's using a contrived example of non-modular design and poor dependency inheritance.

    i think you should consider a singleton factory pattern, where a singleton factory (Auth) provides a login() method which returns a User class, as well as methods for saving state between HTTP requests on that User.

    This will have the benefits of separating the security and session functionality from the User functionality. Additionally using the factory, you can have multiple types of users without the rest of the system needing to understand which object to request before the db is examined

    class auth {
        private static $auth = null;
        private $user = null;
    
        // must use getAuth();
        private __construct(){};
    
        public getAuth() {
            if (is_null($this->auth) {
                 $this->auth = new auth();
            }
            return $this->auth;       
        }
    
        public function login($user,$pass) {
            ... // check db for user,
    
            if ($dbrow->user_type == 'admin') {
                $this->user = new admin_user($dbrow);
            } else {
                $this->user = new normal_user($dbrow);
            }
    
            $this->user->setSession($db->getsession());
        }
    
        public function getUser() {
            return $this->user;
        }
    
        public function saveSession() {
            // store $this->user session in db
        }
    
        public function saveUser() {
            // store $this->user changes in db
        }
        ...
    }
    

    the user class itself become a data structure, simply enforcing security and business rules, and maybe formatting some data for output purposes.

    class normal_user extends user {
        ... getters and setters
        public function getName() {}
        public function setEmail() {}
        public function setprofile() {}
    }
    

    all db, state and security concerns are centralized in the auth. the only way to create a user object (legally) is to run auth->login().

    you are still allowed to do

    $me = new normal_user();
    $me->setName();
    echo $me->getName();
    

    but there is no way for a new coder to save this in the db since it's not referenced in $auth->user;

    you can then create a function in auth to consume user objects to create new users (on signup)

    ...
    public function create(user $user) {
        // validate $user
        $this->user = $user;
        $this->saveUser();
    }
    ...
    

    you just need to make sure you run the save functions at the end of execution... possibly in a destructor()

    simple

提交回复
热议问题