2011-12-21 112 views
1

我正在寫一個PHP應用程序的子類,因爲我想有多種方式來創建一個對象,我正在做不同的工廠方法,而不是多個構造函數。從子類工廠方法PHP調用超類工廠方法

我有一個工廠方法User

User::from_id 
User::from_netid 

我有User幾個子類。我以前調用父superconstructor,但是當我切換到構造函數不存在的工廠方法。

我有StudentUser的子類。爲了得到它的工作,我不得不幾乎所有的User::from_id我父工廠代碼複製到load_by_id,因爲在這種情況下,例如已經存在:

// In Student.php - Student extends User 
public static function from_id_and_course($id, $course){ 
    $instance = new self(); 
    $instance->load_by_id($id); 
    $instance->course = $course; 
    ... 
} 

我想打電話從子類的父類工廠方法一個起點,然後繼續添加其他字段。事情是這樣的......

$instance = User::from_id($id); 

$instance = Student::from_id($id); 

但在這些情況下,它給了我一個User對象,我需要一個Student對象。我能做到這一點的唯一方法就是做$instance = new self()

如何從子類中調用超類工廠方法作爲創建新子類工廠方法的起點?

+0

僅供參考你在這裏沒有實現真正的工廠模式。你打算讓另一個類充當工廠,以便任何想要使用student/users /任何子類的類都鬆散地耦合到那些通過調用用戶類的特定方法而不緊密耦合的類。 – 2011-12-21 01:18:52

+0

@ZeSimon - 這似乎是[工廠方法](http://en.wikipedia.org/wiki/Factory_method_pattern)模式,而不是完整的工廠模式 – HorusKol 2011-12-21 01:20:46

+0

同意,但我認爲在這種情況下,他會受益於完整工廠模式。 – 2011-12-21 01:22:31

回答

5

你的問題是這樣的:

$instance = new self(); 

self指的是方法的定義,而不是調用類:

  • Student::from_id()被調用時,如果它不存在,它回落到User::from_id()
  • User::from_id(),self是指User而不是Student

你不得不使用late-static bindings

$instance = new static(); 

然而,就像我一直做的,我會強烈建議反對。使用對象作用域比靜態作用域更好。擴展,僞造或模擬和偶然地測試更容易。

有什麼不妥:

$user = new User; 
$user->from_id($id); 

$student = new Student; 
$student->from_id($id); 

...它實際上是更好的。

+0

感謝您的回答和建議。 – jkeesh 2011-12-21 01:41:41

1

如果您使用的是PHP 5。3或更高版本,你可以使用Late Static Bindings現在可用:

class User 
{ 
    public static function from_id($id) 
    { 
    // factory 
    $object = new static(); 

    // setup 

    // return 
    return $object; 
    } 
} 

class Student extends User { } 

$student = Student::from_id($id); // $student should be of class Student 

注意 - 你可能會更好過設立了嘲諷/測試/神智整個工廠類...