2011-06-16 72 views
7

我基本上爲我創建的廣告系統創建一個顯示模塊。避免使用面向對象設計的if語句,PHP

我試圖避免以下結構,重複的if語句。

我的直覺告訴我有更聰明的方法來做到這一點,也許與多態?

<?php 

class Ad { 
    public $adState = 'active'; 
} 

class AdWriter { 
    public function displayAd(Ad $ad, $viewmode = 'visitor') { 
     if ($viewmode =='visitor') { 
      if ($adState == 'active') {} 

      else if ($adState == 'paused') {} 

      else if ($adState == 'inactive') {} 

     } 

     else if ($viewmode = 'owner') { 
      if ($adState == 'active') {} 

      else if ($adState == 'paused') {} 

      else if ($adState == 'inactive') {} 
     } 

     else if ($viewmode == 'administrator') { 
      if ($adState == 'active') {} 

      else if ($adState == 'paused') {} 

      else if ($adState == 'inactive') {} 
     } 
    } 
} 

?> 

回答

0

我在工作中潛入StackOverflow,所以沒有時間寫出所有可能性的詳細答覆。在viewmode

switch $viewmode { 
    case 'visitor': 
    your_code_here; 
    break; 
    case 'owner': 
    your_code_here; 
    break; 
    default: 
    will_run_if_nothing_above_matches; 
    break; 
} 
+2

他問了一個更聰明的方法,並且你展示了它。好。 :) – 2011-06-16 11:23:17

+2

這並沒有真正消除任何東西,但?我仍然堅持不斷地檢查各州。 – Poyan 2011-06-16 11:26:14

+0

-1這與我將研究的ifs – Gordon 2011-06-16 11:34:39

4

您可以創建一個Factory (Pattern),使用開關,並創建一個特定Ad實現一個interface有一個簡單的函數「顯示:

但要「收拾」那些如果,你可以這樣做' 例如。

僞例如:

class AdFactory { 

    public static function getAd($sType) { 
     switch($sType) { 
      case "AdOne": 
       return new AdOne(); 
      case "AdTwo": 
       return new AdTwo(); 
     } 
    } 
    throw new Exception("Unknown ad!"); 
} 

class AdOne implement AdInterface { 
    public function display() { 
     // All that AdOne does when displaying. 
    } 
} 

interface AdInterface { 
    public function display() { } 
} 

$oAd1 = AdFactory::getAd('typeOne'); 
$oAd1->display(); 

$oAd2 = AdFactory::getAd('typeTwo'); 
$oAd2->display(); 
+0

實際上是相同的;謝謝。 – Poyan 2011-06-16 11:27:14

3

強似$視圖模式中,傳遞了一個對象,將封裝邏輯此viewmore並調用它的方法,會做的工作。這樣你就可以避免if語句的需要。

0
switch($viewmode){ 
    case "visitor": 
     switch($adstate){ 
      case "active": 
       //statement 
       break; 
      case "paused": 
      break; 
      case "inactive": 
      break; 
     } 
     break; 
    case "owner": 
     break; 
    case "administrator": 
     break; 
} 
0

this book的第8章中,您可以找到非常詳細的問題答案。

總之:使用Composition或工廠。 (見Wesley van Opdorp的答案)。

此外,應避免使用字符串參數作爲枚舉: $viewmode = 'visitor'
有這樣的說法,你將不得不在內存中保留這種說法的所有可能的值。或者查看功能代碼來記住它們。這些值是字符串 - 錯別字的好地方。此外,要更改特徵中的值將非常困難,因爲此方法的所有調用都將包含硬編碼的字符串。
使用類常數:

class AdWriter { 
const view_mode_visitor = 1; 
... 

此外,$adState - 錯誤的代碼,應該是$ AD->狀態。但使用公共領域這也是不好的做法:)