扩展类通过NULL - OOP

时间:2017-11-03 09:16:45

标签: php class oop extends

我的所有用户方法都有以下类:

class User {
  protected $_db,
            $_data;

  public function __construct($user = null, $findby = 'id') {
    $this->_db = DB::getInstance();

    if (!$user) {
      ........
    } else {
      ........
    }
  }

 .......

  public function login($username = null, $password = null) {
    $user = $this->find($username, 'username');
    if ($user) {
      $lockdown = new Lockdown; 
    }
  }

  public function find($param = null, $method = null) {
    if ($param && $method) {
      $data = $this->_db->query("SELECT * FROM users ...");
      if ($data->count()) {
        $this->_data = $data->result();
        return true;
      }
    }
    return false;
  }

  public function data() {
    return $this->_data;
  } 
}

以上是我的用户类的完全剥离版本。我还有另一个类(锁定)扩展用户:

class Lockdown extends User {
  public $getAttempts;

  public function __construct() {
    var_dump($this->data());
    die();
  }
}

但是当我在登录类中调用lockdown类时,即使数据对象应该包含所有用户信息,var_dump()也只是返回NULL。

根据我的计算,当调用登录类时,查找方法应设置$ _data = USER INFO,因此应允许在($ this-> find)之后调用新的Lockdown方法())能够访问相同的数据方法。

我还在学习OOP编程,所以不知道是否有我遗漏的东西,但我似乎无法理解为什么Lockdown类在数据方法上返回NULL的原因应该继承它。

1 个答案:

答案 0 :(得分:2)

您不应该在构造函数中放置任何计算逻辑。这使得测试变得困难。您也无法从构造函数返回。

你的结构是一场彻底的灾难。两者都是因为你滥用继承和全球国家。

为类创建自己的子类的新实例以检索数据是没有意义的。这可能是因为您试图让User类结合两个不同的职责:持久性和业务逻辑。这违反了Single Responsibility Principle,然后以复杂的调用图形式显示。

整个class Lockdown extends User构造也毫无意义。 OOP中的extends关键字可以翻译为"是"的特殊情况。 (根据LSP)。跟踪用户登录尝试的类不是" user"的专门案例。

你应该至少有3个单独的类:一个用于处理"用户的行为"和其他用于保存/恢复"用户的状态" (该方法称为" data mapper")。第三个是管理失败的尝试。

我还强烈建议您观看this lecture

对于全局状态,您应该将数据库连接作为构造函数的依赖项传递给类,而不是使用单例反模式,这需要与持久性进行交互。

至于代码,在高级别,它应该看起来像这样:

$user = new User;
$mapper = new UserMapper($db);

$user->setName($username)
if ($mapper->fetch($user)) {
   if ($user->matchPassword($password)) {
       // you have logged in
       // add some flag in session about it
       header('Location: /greetings');
       exit;
   }
   // check the failed attempts
} else {
  // no matching username 
}