如何用PHP中更灵活的代码替换switch语句?

时间:2012-04-09 14:22:17

标签: php oop design-patterns

我的数据库中有一个名为帖子的表格。每个帖子都有一个名为 social_network

的字段

当我在代码中将所有帖子放入数组时,我需要根据它的 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
  }
}

3 个答案:

答案 0 :(得分:7)

为FacebookPost和TwitterPost类添加一个接口(例如SocialPostInterface),它定义了相同的基本必要方法,如getId()postToNetwork()然后您可以添加任意数量的新社交网络,而无需改变这段代码。他们只需实现界面

然后体验多态性的力量:

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();
}

答案 1 :(得分:4)

我不认为你可以避免这种代码。但是您可能希望将其移动到抽象工厂中,因此您无需在控制器中查看它。

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

答案 2 :(得分:1)

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

您可以从保存其名称的字符串中创建一个新对象。