处理对象依赖
Handling Object Dependency
考虑以下 class
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 并应用所需的更改。
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());
}
}
根据我的理解,这不是推荐的方法,因为我在这里看到两个问题
- Bcrypt() 被实例化了两次
- 这使得 User 对象与 Bcrypt 紧密耦合
我可以通过在 class 构造函数中实例化一次 Bcrypt() 并在需要时使用它来解决问题 1,但这并不能解决问题 2
方法 2: 将 Bcrypt 对象移出用户 class 并在设置密码时注入它
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
}
最好的解决方法是什么?
谢谢。
我想第一种方法更好,因为它 隐藏 在用户 class.
中使用 bcrypt
我不认为其他程序员必须记住他在使用 User
class.
时必须使用,例如,$bcrypt->verify
也许您可以创建一个密码 class 并将此逻辑移到那里?
您可以这样做:
class Password
{
private $password;
public __construct($password)
{
$this->password = $password;
}
public crypt(Zend_Crypt_Password_PasswordInterface $crypt)
{
$this->password = $crypt->create($password);
}
}
或使用 Decorator。
这两种解决方案都为您提供了扩展代码的可能性。
除了 Zend_Crypt_Password_PasswordInterface
,您还可以使用自己的 Wrapper。恕我直言,这将是更好的解决方案。
然后您可以为特定用户设置密码,它不关心它是否被加密、散列或其他:
class User
{
private $password;
public function changePassword(Password $password)
{
$this->password = $password;
}
}
考虑以下 class
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 并应用所需的更改。
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());
}
}
根据我的理解,这不是推荐的方法,因为我在这里看到两个问题
- Bcrypt() 被实例化了两次
- 这使得 User 对象与 Bcrypt 紧密耦合
我可以通过在 class 构造函数中实例化一次 Bcrypt() 并在需要时使用它来解决问题 1,但这并不能解决问题 2
方法 2: 将 Bcrypt 对象移出用户 class 并在设置密码时注入它
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
}
最好的解决方法是什么?
谢谢。
我想第一种方法更好,因为它 隐藏 在用户 class.
中使用 bcrypt我不认为其他程序员必须记住他在使用 User
class.
$bcrypt->verify
也许您可以创建一个密码 class 并将此逻辑移到那里? 您可以这样做:
class Password
{
private $password;
public __construct($password)
{
$this->password = $password;
}
public crypt(Zend_Crypt_Password_PasswordInterface $crypt)
{
$this->password = $crypt->create($password);
}
}
或使用 Decorator。
这两种解决方案都为您提供了扩展代码的可能性。
除了 Zend_Crypt_Password_PasswordInterface
,您还可以使用自己的 Wrapper。恕我直言,这将是更好的解决方案。
然后您可以为特定用户设置密码,它不关心它是否被加密、散列或其他:
class User
{
private $password;
public function changePassword(Password $password)
{
$this->password = $password;
}
}