在PHP laravel中,我们有像
这样的代码$user = User::find(1);
var_dump($user->name);
我不关心如何使用find
方法,我担心为什么laravel使用静态方法?不应该使用静态方法使该方法难以测试吗?
如果他们使用单身人士设计会更好吗?
e.g。
$user = User::getInstance()->find(1);
var_dump($user->name);
答案 0 :(得分:16)
事实上,你的例子与Laravel在场景背后的表现非常相似。当你执行User::find()
时,实际上是在要求一个新实例,可以是Collection的实例,也可以是QueryBuilder。
照亮\数据库\ Eloquent \ Model(reference):
public static function find($id, $columns = array('*'))
{
if (is_array($id) && empty($id)) return new Collection;
$instance = new static;
return $instance->newQuery()->find($id, $columns);
}
作为旁注,您还会看到另一种在Laravel中使用静态方法的方法,例如: Input::get()
。这些被称为外墙。
了解有关Larave外墙的更多信息外墙提供静电"与应用程序的IoC容器中可用的类的接口... Laravel" facades"作为"静态代理"到IoC容器中的底层类,提供简洁,富有表现力的语法,同时保持比传统静态方法更多的可测试性和灵活性。
当用户引用... facade上的任何静态方法时,Laravel会解析来自IoC容器的缓存绑定,并针对该对象运行所请求的方法(在本例中为get)。
答案 1 :(得分:14)
Unnawut有一个非常好的答案,但我觉得有必要加上进一步的解释。
在你的例子中
$user = User::find(1);
var_dump($user->name);
Laravel没有使用静态方法,你是。你可能正在寻找的另一种方法是使用依赖注入,Laravel非常容易,因为它可以自动完成。所以在你使用User
模型的任何类中,都应该在构造函数中设置类似的东西......
public function __construct(User $user)
{
$this->user = $user;
}
然后您可以修改代码以不使用静态绑定。
$user = $this->user->find(1);
var_dump($user->name);
答案 2 :(得分:2)
这会限制系统只有一个用户。虽然find
方法可能是静态的,但User类将具有其他方法和属性,例如:$user->name
不依赖于任何实例变量的方法,即,变量的值是特定于特定对象实例的,但是提供适用于所有实例的通用功能,可以并且可能应该是静态的。这就是$this
运算符在静态方法中是非法的原因,因为它不能引用特定的对象实例。
答案 3 :(得分:-2)
在GRASP patterns之后,用户对象无法搜索用户。
您需要一种Filter或Collection对象,::find()
方法可帮助您创建Collection过滤器并将结果转换为有用的实体。
对于User
实体的使用,您只需更改属性的值并检索值。该实体没有责任根据条件搜索实例。
通过这种逻辑,您将能够以原子碎片的形式解耦代码中的逻辑。