Говорят, что "статические методы - это смерть для проверки" . Если это так, какова жизнеспособная альтернативная схема для ниже?
class User {
private $phone,
$status = 'default',
$created,
$modified;
public function __construct($phone) {
$this->phone = $phone;
$this->created = new DateTime;
$this->modified = new DateTime;
}
public static function getByPhone(PDO $pdo, $phone) {
$stmt = $pdo->prepare('SELECT * FROM `users` WHERE `phone` = :phone');
$stmt->execute(compact('phone'));
if (!$stmt->rowCount()) {
return false;
}
$record = $stmt->fetch(PDO::FETCH_ASSOC);
$user = new self($record['phone']);
$user->status = $record['status'];
$user->created = new DateTime($record['created']);
$user->modified = new DateTime($record['modified']);
return $user;
}
public function save(PDO $pdo) {
$stmt = $pdo->prepare(
'INSERT INTO `users` (`phone`, `status`, `created`, `modified`)
VALUES (:phone, :status, :created, :modified)
ON DUPLICATE KEY UPDATE `status` = :status,
`modified` = :modified');
$data = array(
'phone' => $this->phone,
'status' => $this->status,
'created' => $this->created->format('Y-m-d H:i:s'),
'modified' => date('Y-m-d H:i:s')
);
return $stmt->execute($data);
}
...
}
Это просто сокращенный пример. Класс имеет еще несколько методов и свойств, а также более валидацию при записи в базу данных и т.д. Принцип руководящего принципа этого класса заключается в том, что он моделирует пользователя как объект. Некоторые из свойств объекта не могут быть изменены после его создания, например номер телефона (который действует как первичный идентификатор), дату создания пользователя и т.д. Другие свойства могут быть изменены только в соответствии со строгими бизнес-правилами, которые все строго проверяют сеттеры и геттеры.
Объект не представляет собой запись базы данных как таковой, база данных рассматривается только как одна из возможных форм постоянного хранения. Таким образом, соединитель базы данных не сохраняется в объекте, а требует его инжекции каждый раз, когда объект должен взаимодействовать с базой данных.
Когда создается новый пользователь, это выглядит так:
$user = new User('+123456789');
Когда существующий пользователь восстанавливается из постоянного хранилища, это выглядит так:
$pdo = new PDO('...');
$user = User::getByPhone($pdo, '+123456789');
Если бы я серьезно относился к теме "смерть к испытанию", это, предположительно, плохо. Я отлично могу протестировать этот объект, потому что он полностью вливается и методы static
не имеют состояния. Как я могу сделать это по-другому и избегать использования методов static
? Вернее, что именно противоречит static
в этом случае? Что делает такое использование методов static
настолько трудным для тестирования?