处理对象依赖

时间:2016-02-04 05:54:20

标签: php oop dependency-injection loose-coupling

考虑以下课程

class User
{
    protected $password;

    public function setPassword($password)
    {
        $this->password = $password;
        return $this;
    }

    public function getPassword()
    {
        return $this->password;
    }
}

我想在用户对象中使用Zend\Crypt\Password\Bcrypt在密码上应用bcrypt,因为这会创建一个依赖关系,我想知道如何正确处理这个问题,我可以考虑几种方法来完成这项工作,让我详细说明

方法1 :这里我们在方法中实例化类并应用所需的更改。

class User
{
    protected $password;

    public function setPassword($password)
    {
        $bcrypt = new Bcrypt();
        $this->password = $bcrypt->create($password);
        return $this;
    }

    public function getPassword()
    {
        return $this->password;
    }

    public function verifyPassword($password)
    {
        $bcrypt = new Bcrypt();
        return $bcrypt->verify($password, $this->getPassword());
    }
}

据我所知,这不是推荐的方法,因为我在这里看到两个问题

  1. Bcrypt()实例化两次
  2. 这使得User对象与Bcrypt
  3. 紧密结合

    我可以通过在类构造函数中实例化一次Bcrypt()来解决问题-1,并在需要时使用它,但是这不能解决问题-2

    方法2:将Bcrypt对象移出用户类并在设置密码时将其注入

    class User
    {
        protected $password;
    
        public function setPassword($password)
        {
            $this->password = $password;    
            return $this;
        }
    
        public function getPassword()
        {
            return $this->password;
        }
    }
    
    // Init Bcrypt
    $bcrypt = new Bcrypt;
    
    // Instantiate user object and create a password
    $user = new User;
    $user->setPassword($bcrypt->create($password));
    
    // Verify user password
    if ($bcrypt->verify($password, $user->getPassword())) {
        // Password is verified
    }
    

    关于它的最佳方式是什么?

    感谢。

2 个答案:

答案 0 :(得分:1)

也许你可以创建一个Password类并在那里移动这个逻辑? 你可以这样做:

SomeClass

或使用Decorator。 这两种解决方案都为您提供了扩展代码的可能性。 您也可以使用自己的Wrapper代替class Password { private $password; public __construct($password) { $this->password = $password; } public crypt(Zend_Crypt_Password_PasswordInterface $crypt) { $this->password = $crypt->create($password); } } 。这将是恕我直言更好的解决方案。

然后你可以为特定用户设置密码,它不关心它是加密,散列还是其他:

Zend_Crypt_Password_PasswordInterface

答案 1 :(得分:0)

我认为第一种方法更好,因为它的隐藏在用户类中使用了bcrypt。

我不认为其他程序员必须记住,在使用$bcrypt->verify类时,他必须使用User