2012-04-09 88 views
0

我在我的數據庫中有表名爲的帖子。每個有場名爲SOCIAL_NETWORK如何用PHP中更靈活的代碼替換switch語句?

當我得到的所有帖子到陣列中的我的代碼需要根據它的SOCIAL_NETWORK領域創造了每一個實例。

現在我使用switch語句,但我不喜歡它,因爲它不靈活。

$posts = DataBase::getPosts(); // pseudocode 
foreach($posts as $post) { 
    switch($post->getSocialNetwork()){ 
    case 'Facebook': 
     $social = new FacebookPost($post->getId()); 
     break; 
    case 'Twitter': 
     $social = new TwitterPost($post->getId()); 
     break;   
    // .... other social networks 
    } 
} 
+0

它如何在你所做的事情上不靈活? – Sarfraz 2012-04-09 14:25:35

回答

6

添加到已經定義了基本相同的必要方法,如getId()類FacebookPost和TwitterPost(如SocialPostInterface)的接口,postToNetwork()然後你可以根據需要添加許多新的社交網絡,而不必改變這片的代碼。他們只是要實現接口

然後體驗polymorhpism的功率:

foreach ($posts as $post) { 
    $className = $post->getSocialNetwork() . 'Post'; 
    // lets check if such class exists 
    if (!class_exists($className, false /* do not attempt autoload */)) { 
     throw new Exception("Unknown social network post class $className"); 
    } 
    $social = new $className($post->getId()); 
    $social->doSomeStuffThatTheInterfaceHasDeclared(); 
} 
+0

基於他的代碼,他已經在使用多態性......另外,PHP使用鴨子打字,沒有力量使用共同的祖先或界面(儘管將它作爲文檔使用是個好主意) – 2012-04-09 14:30:29

+0

謝謝Capitan Obvious 。重構該特定部分以擺脫代碼重複並簡化代碼維護。沒有什麼能夠強制你實現接口,這是真的,但是很容易忘記一個沒有接口的實現方法 - 它被用作文檔,是一種很好的練習,這將爲他節省時間和麻煩。 – ddinchev 2012-04-09 14:37:55

+0

@ DampeS8N,我編輯了代碼。 – ddinchev 2012-04-09 14:40:28

1
$socialClass = $post->getSocialNetwork() . 'Post'; 
$social = new $socialClass($post->getId()); 

您可以從一個串保持它的名字做一個新的對象。

4

我不認爲你可以避免這種類型的代碼。但是您可能想將其移入抽象工廠,因此您不必在控制器中查看它。

$posts = DataBase::getPosts(); // pseudocode 
foreach($posts as $post) { 
    $social = SocialFactory::post($post); 
    } 
} 
+0

http://en.wikipedia.org/wiki/Abstract_factory_pattern – 2012-04-09 14:31:53

+0

這只是簡單的工廠方法 - http://en.wikipedia.org/wiki/Factory_method_pattern – 2012-04-09 14:36:52