[英]php static functions vs instance functions, basics
我正在努力學習何時應該使用靜態函數,並且很難找到答案我的問題。 我正在創建一個類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
}
第二種方法創建一個從未使用過的空組對象。 有關系嗎? 我是否誤解了靜態的概念? 我知道它不需要實例化一個類是有用的,所以如果函數實例化一個,那么這樣做是否會失敗? 如果是這樣,那么什么時候使用靜態函數會是什么?
在這個簡化的例子中我還應該考慮其他什么嗎?
在上面顯示的情況下,您不需要靜態函數。
靜態函數實際上只是具有命名空間的全局函數。
當需要控制應用程序的全局狀態時,或者如果函數的多個副本導致不一致的結果時,請使用它們。
回調有時需要是靜態的,特別是如果它們作為字符串傳遞。
你應該在Active Record vs data mapper上查看這個問題:
https://stackoverflow.com/questions/2169832/data-mapper-vs-active-record
從這個問題中可以看出,在大多數情況下,用於加載/保存的類上的靜態方法實際上並不是該類的核心功能。 此外,存儲和加載是一種抽象概念,在大多數情況下與您的類對象是分開的。
Isa“用戶”是一個數據存儲和檢索對象? 在大多數情況下,不,它是系統中代表的具有各種屬性和功能的人。 當您開始將該對象的持久性綁定到對象中時,您將破壞封裝並使維護代碼變得更加困難。 如果下周你想從memcache加載你的用戶怎么辦? 如果用戶可以擁有某些屬性或功能,則幾乎無關緊要。
我發現一個好的經驗法則是“如果我沒有[類名],我希望能夠調用[方法名]嗎?”
如果我沒有用戶,我希望能夠調用findByID嗎? 可能不是。 這是我遇到的例外之一; “加載”或“保存”方法有時是靜態的。
何時使用非靜態方法的一個完美示例是(數據庫類中的大多數方法) - 在嘗試對其運行查詢之前,應始終擁有數據庫對象。
何時使用靜態方法的一個例子是“輔助”類,本質上是一組方便的函數。 假設你有一些方法可以幫助你輸出HTML,你可能有HTML::image()
, HTML::url()
和HTML::script()
。 在這些上,您不需要HTML對象來創建圖像,URL等。
至於停止正在創建的對象的多個副本(使用靜態方法的一個參數),您應該使用Singleton模式(Google it)來確保只存在一個對象副本。
我正在嘗試學習何時應該使用靜態函數
哦,這很簡單: 從來沒有 。
要理解它,請閱讀:
http://www.objectmentor.com/resources/articles/ocp.pdf
http://misko.hevery.com/code-reviewers-guide/flaw-brittle-global-state-singletons/
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.