避免使用面向对象设计的if语句,PHP

时间:2011-06-16 11:18:51

标签: php oop if-statement

我基本上是为我创建的广告系统创建一个显示模块。

我试图避免以下构造,重复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') {} 
        } 
    } 
}  

?>

6 个答案:

答案 0 :(得分:11)

答案 1 :(得分:4)

您可以使用viewmode上的开关创建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();

答案 2 :(得分:3)

不是传递$ viewmode,而是传递一个对象,该对象将封装此视图的逻辑,并调用其方法来完成工作。这样你就可以避免使用if语句了。

答案 3 :(得分:0)

我在工作中潜入StackOverflow,所以没有时间写下你所有可能性的详细回复。

但要“整理”那些ifs,你可以这样做:

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

答案 4 :(得分:0)

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

答案 5 :(得分:0)

this book的第8章中,您可以找到对您问题的非常详细的答案。

简而言之:使用Composition或工厂。 (见Wesley van Opdorp的回答)。

另外,避免使用字符串参数作为枚举: $viewmode = 'visitor'
使用此参数,您必须将此参数的所有可能值保留在内存中。或者查看函数代码来记住它们。这些价值观是字符串 - 拼写错误的好地方。此外,更改要素中的值将非常困难,因为此方法的所有调用都将包含硬编码字符串 使用类常量:

class AdWriter { 
const view_mode_visitor = 1;
...

此外,$adState - 错误代码,应为$ ad-&gt;州。但是使用公共领域也是不好的做法:)