我正在努力学习何时应该使用静态函数,并且很难找到答案我的问题。我正在创建一个类User
,它与类Group
相关。如果我有一个用户ID,并且我想从中获取用户对象,那么最好做一些像
$existingUser = User::get($userId);
这里的类定义如下
class User()
{
public static function get($id){
$user = new User();
return $user->findById($id);
}
public function findById($id) {
//find and populate user object
}
}
或
$existingUser=new User();
$existingUser->findById($userId);
这里的类定义如下
class User()
{
public function findById($id) {
//find and populate user object
}
}
如果我要编写一个基于用户ID返回Group对象数组的函数呢?
class User()
{
//stuff
$groupArray = Group::getAllByUserId($this->getId())
//stuff
}
或
class User()
{
//stuff
$group = new Group();
$groupArray = $group->findAllByUserId($this->getId());
//stuff
}
第二种方法创建一个从未使用过的空组对象。有关系吗? 我是否误解了静态的概念?我知道它不需要实例化一个类是有用的,所以如果函数实例化一个,那么这样做是否会失败?如果是这样,那么什么时候使用静态函数会是什么?
在这个简化的例子中我还应该考虑其他什么?
答案 0 :(得分:0)
如上所示,您不需要静态函数。
静态函数实际上只是具有命名空间的全局函数。
当需要控制应用程序的全局状态时,或者如果函数的多个副本导致不一致的结果时使用它们。
回调有时需要是静态的,特别是如果它们作为字符串传递。
答案 1 :(得分:-2)
你应该在Active Record vs data mapper上查看这个问题:
https://stackoverflow.com/questions/2169832/data-mapper-vs-active-record
从这个问题中可以看出,在大多数情况下,用于加载/保存的类的静态方法实际上并不是该类的核心功能。此外,存储和加载是一种抽象概念,在大多数情况下与您的类对象是分开的。
Isa"用户"数据存储和检索对象?在大多数情况下,不,它是系统中代表的具有各种属性和功能的人。当您开始将该对象的持久性绑定到对象中时,您将破坏封装并使维护代码变得更加困难。如果下周你想从memcache加载你的用户怎么办?如果用户可以拥有某些属性或功能,这几乎无关紧要。
答案 2 :(得分:-2)
我发现一个好的经验法则是“如果我没有[类名],我希望能够调用[方法名称]吗?”
如果我没有用户,我希望能够调用findByID吗? 可能不是。这是我遇到的例外之一; “加载”或“保存”方法有时是静态的。
何时使用非静态方法的一个完美示例是(数据库类中的大多数方法) - 在尝试对其运行查询之前,应始终拥有数据库对象。
何时使用静态方法的一个例子是“辅助”类,本质上是一个方便函数的集合。假设您有一些方法可以帮助您输出HTML,您可能有HTML::image()
,HTML::url()
和HTML::script()
。在这些上,您不需要HTML对象来创建图像,URL等。
至于停止正在创建的对象的多个副本(使用静态方法的一个参数),您应该使用Singleton模式(Google it)来确保只存在该对象的一个副本。
答案 3 :(得分:-2)
我正在尝试学习何时应该使用静态函数
哦,这很简单:从不。
要理解它,请阅读:
http://www.objectmentor.com/resources/articles/ocp.pdf
http://misko.hevery.com/code-reviewers-guide/flaw-brittle-global-state-singletons/