在OO编程中,我们会瞧不起使用魔术方法__get()
和__set()
,这些会导致封装泄漏出类吗?例如:
class User {
private $username;
private $password;
public function __set($name,$value) {
$this->$name = $value;
}
public function __get($name) {
return $this->$name;
}
}
这有效地使private
/ protected
变量public
成为可能。
答案 0 :(得分:5)
您的代码:
class User {
private $username;
private $password;
public function __set($name,$value) {
$this->$name = $value;
}
public function __get($name) {
return $this->$name;
}
}
在这种情况下,是完全没必要的。
封装does not mean“一堆吸气剂和二传手”。您可以将其重构为:
class User {
public $username;
public $password;
}
就封装而言,它们是等价的。
一般来说,__get
和__set
有一些用途,但是如果你不能这样做,你应该(特别是考虑到它们比正常的方法定义"considerably slower")。
答案 1 :(得分:0)
如果你那样使用它,那么是的。行为将完全相同,您应该只使用公共变量,因为这在PHP中更快。
setter有用的东西是在实际分配值之前检查值:
public function __set($name, $value)
{
switch($name)
{
case 'username':
if(strlen($value) < 6 || strlen($value) > 30)
throw new Exception();
...
break;
case 'password':
//some security checks
break;
default: throw Exception('no property'.$name);
}
$this->$name = $value;
}
答案 2 :(得分:0)
这个问题没有严格的是/否答案。相反,有一个解释:
从纯粹的面向对象的角度来看,是的,这是一个漏洞的封装。为什么?考虑一个类具有许多属性的情况,每个属性都有一个getter和一个setter。现在,如果在大型复杂的应用程序中使用此类,在许多地方以及在许多方面,则很难控制对象的状态(属性值),因为它可以在很多方面进行修改/更改位置,通过附件(吸气剂和制定者)。那么,解决方案是什么?嗯,一般来说,更好的设计是通过构造函数构造一个对象。例如,User类可以重新设计为:
class User {
private username;
private password;
// constructor
public User(name, password) {
this->username = name;
this->password = password;
}
// other methods
}
在这个新设计中,只有一种方法可以使用构造函数创建User类型的对象。这可以保证以受控方式以已知方式创建对象,因此可以随时了解其行为。
考虑到上面的论点,它不是使封装泄漏的getter,而是setter,因为它们是修饰符;除了构造时间之外,任何时候都可以修改对象1)在构造函数2之外的状态。
总而言之,有些情况下,必须为一个班级提供getter和setter。例如,某些对象关系框架需要这样,因为它们能够修改对象。