php静态函数vs实例函数,基础知识

时间:2011-09-16 22:33:02

标签: php oop static static-functions

我正在努力学习何时应该使用静态函数,并且很难找到答案我的问题。我正在创建一个类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
}

第二种方法创建一个从未使用过的空组对象。有关系吗? 我是否误解了静态的概念?我知道它不需要实例化一个类是有用的,所以如果函数实例化一个,那么这样做是否会失败?如果是这样,那么什么时候使用静态函数会是什么?

在这个简化的例子中我还应该考虑其他什么?

4 个答案:

答案 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/