2012-04-09 51 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