2012-06-22 17 views
1

我正在瀏覽一個對象列表,它們都具有相同的父類,但它們可以是來自許多子類之一的實例。根據對象的真實類型,我想執行稍微不同的操作。如何根據對象的真實類名運行代碼?

如何根據對象類型運行不同的代碼塊?

在Java中,我會重載一個處理函數,每種類型我都想處理,但PHP不允許這樣做。

背景: 對戈登的評論。

我們正在從一組對象構建表單。超類組件,擴展後表示特定類型的表單元素。 TextInput extends Component和組件有能力容納其他組件。我們不希望他們對其實際表示負責。

我們正在努力構建HTML,但我們可能希望使用它們來構建.PDF或其他格式。

所以我們有遍歷組件的代碼,並遞歸地通過它包含的組件。根據組件的類型,我們需要創建不同的輸出。

+0

請爲您的問題提供更多背景。感覺就像你在爲錯誤的問題尋求解決方案。這聽起來像對我來說放錯了方法。不要查詢對象的類型,然後做一些事情,告訴對象做些什麼。這叫做「不要問」。 – Gordon

+0

@戈登編輯了一些背景。我們不希望這些對象負責它們的輸出,所以Tell Do not Ask不會工作。 – Chris

回答

2

使用

if($myobject instanceof class1){ 
}elseif($myobject instanceof class1){ 
} 

或者

switch(get_class($myobject)){ 
    case 'class1': 
     break; 
    case 'class2': 
     break; 
} 

此外,請蘇爾你不破開/關原則。如果你把代碼部分的一類,而不是在控制器的特定部分,你最終會破壞你的代碼的一個重要的可重用性特點:

開/閉原則

你從來沒有做過一個插件系統?如果你這樣做,我相信你沒有 要求你的用戶在代碼中加載一條加載線來處理該 插件的權利?

通常來說,您希望您的課程可以擴展,而不需要 需要更改父級。擴展應該是一個開放的原則 其中添加更多的代碼應該像擴展一樣簡單,但您應該不必修改父類。

因此addind開關母公司內部或其他類中來處理 該類的所有可能的版本打破了開放性原則,因爲用戶 則必須改變類增加更多的功能...

+0

關於打開/關閉的好處,但我們正在做的是構建數據結構的表示。增加了一些背景問題。我使用類型提示在方法內添加了默認值,可以爲將來的任何未知類型創建默認功能。 – Chris

2
  1. 做一個abstract class代表所有的對象的公共功能,還決定什麼其他的方法,他們必須這樣可以確保你使用相同的接口每次(這些被稱爲abstract methods)工作。

  2. 然後爲每個特定類型的對象創建子類。他們必須實現所有抽象類的主要抽象方法。

  3. 然後使用​​根據任何標誌確定對象類型(a.k.a子類)來動態創建適當的對象。

2

嘗試水木清華這樣

function objectProcessor_A($o) {} 
function objectProcessor_B($o) {} 
function objectProcessor_C($o) {} 

foreach($objects AS $o) { 
    if(function_exist("objectProcessor_" . get_class($o))) 
     call_user_func("objectProcessor_" . get_class($o), $o); 
} 

現在,我認爲,最好的解決辦法是使用繼承。無法更改$ o的行爲/庫代碼?不是使用工廠,並添加方法,匿名函數:

class OFactory { 
    static function getO($type) { 
     $r = new $type(); 
     if($type === "A") { 
      $r.processor = function() {...}; 
     } else if($type === "B") { 
      $r.processor = function() {...}; 
     } else if($type === "C") { 
      $r.processor = function() {...}; 
     } 
     return $r; 
    } 
} 

$a = OFactory::getO("A"); 
call_user_func($a->processor); 

$b = OFactory::getO("B"); 
call_user_func($b->processor); 
+0

這工作得很好,但考慮到Mathieu的答案,它允許默認功能。如果我有30個不同的對象,其中只有5個是特殊情況,其餘的可以回到'default:' – Chris

相關問題