简体:如何避免在模型中使用静态方法?
Loquacious:假设我有一个用户类。有了userID,我可以通过(new user($userID))->getUserName()
获得用户名。好吧,如果我想查找用户呢?(new user())->lookup($uname, $pass)
。仍然很好,但后一种情况可以通过一个简单的静态方法user::lookup($uname, $pass)
来完成!
一些想法:
- 没关系!随时使用
(new object())->method()
。那么我应该创建一个空对象来调用函数吗? - 将此函数移出模型。如果它需要数据库查找,哪里比模型上下文更好?
- 定义为静态方法。那么,在一个类中混合使用公共方法和静态方法不是很蹩脚吗?
旁注:我已经搜索了这个问题,没有效果!
将此函数移出模型。如果它需要数据库查找,哪里比模型上下文更好?
是的,的确,这是解决问题的最好办法。
目前你的User
类违反了单一责任原则,基本上是说"一个任务-一个类"。
现在你的User
描述用户实体/状态并处理持久性(在你的情况下-从数据库检索)。看,有两件事。
我建议你创建另一个类来处理持久化任务,比如添加/更新/删除用户。最简单的解决方案是创建一个原始存储库,如下所示:
<?php
class UserRepository
{
public function addUser(User $user);
public function updateUser(User $user);
public function deleteUser(User $user);
public function getUserById($id);
}
则可以按以下方式检索用户:
// get an instance of this repository class
$userRepository = new UserRepository;
// ask it to find and return user from the database by ID
$user = $userRepository->getUserById($_GET['id']);
易于阅读,易于操作,对吗?
这个UserRepository
类实际上是存储库模式的原语实现。UserRepository
模拟所有用户的内存集合,将实现隐藏在其中。它对作为用户的你隐藏了实际的持久化机制:想象一下,你的同事会写这个类,而你只是使用它的方法,比如UserRepository::getById(1)
——你甚至不知道/关心它是否从文件/db/API中抓取数据。这很好。)
这个特殊的实现在Kristopher Wilson的书"The Clean Architecture in PHP"中有非常清晰的描述,我强烈推荐你阅读:它将花费你两到三个晚上,并将你推向一个新的水平。
当然,你可以扩展方法列表,添加查找等等。
class UserRepository
{
public function getByCompany(Company $company);
public function getByEmail($email);
public function countTotal();
}
事实上,每次你需要在数据库中抓取/添加/更新用户,你应该通过这个存储库来做。
我想强调这是模式的一个简单实现,特别是,如果您将它与Martin Fowler所描述的Repository进行比较的话。但是,在大多数情况下,这是完全可以的。
-
没关系!随时使用(new object())->method()。那么我应该创建一个空对象来调用函数吗?
取决于创建实例的成本
-
将此函数移出模型
这里我想到的是工厂模式。
指出:
当第一次调用中的
$userID
不存在时会发生什么?难道你的
lookup()
方法没有在一次调用中创建2个实例,首先用于查找,其次是返回的找到的一个?
findByID()
或findByName()
并返回一个UserObject。所有这些都不应该依赖于这个语法:(new object())->method()
,这很好,但并不总是最佳实践。