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

发布于 2024-11-15 20:45:29 字数 874 浏览 4 评论 0原文

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

我试图避免使用重复的 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') {} 
        } 
    } 
}  

?>

I'm basically creating a display-module for an ad-system I've created.

I'm trying to avoid the following construction, with repeated if-statements.

My gut feeling tells me there's a smarter way to do this, maybe with polymorphism?

<?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') {} 
        } 
    } 
}  

?>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

软糖 2024-11-22 20:45:29

您可以创建一个 工厂(模式),使用 viewmode 开关并创建实现 界面例如具有简单的功能“显示”。

伪示例:

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

You could create an Factory (Pattern), using an switch on viewmode and create an specific Ad implementing an interface having an simple function 'display' for example.

Pseudo example:

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();
伏妖词 2024-11-22 20:45:29

不要传递 $viewmode,而是传递一个封装此 viewmore 逻辑的对象,并调用其执行该工作的方法。这样您就可以避免使用 if 语句。

Instead of passing $viewmode, pass an object that would encapsulate the logic for this viewmore and call its method that would do the work. This way you'll avoid the need for if-statements.

鸠魁 2024-11-22 20:45:29

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

但要“整理”这些 if,您可以这样做:

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

I'm sneaking onto StackOverflow at work, so don't have time to write a detailed reply of all your possibilities.

But to 'tidy up' those ifs, you can do this:

switch $viewmode {
  case 'visitor':
    your_code_here;
    break;
  case 'owner':
    your_code_here;
    break;
  default:
    will_run_if_nothing_above_matches;
    break;
}
旧话新听 2024-11-22 20:45:29
  switch($viewmode){
    case "visitor":
        switch($adstate){
            case "active": 
                //statement
                break;
            case "paused": 
            break;
            case "inactive": 
            break;
        }
        break;
    case "owner":
        break;
    case "administrator":
        break;
}
  switch($viewmode){
    case "visitor":
        switch($adstate){
            case "active": 
                //statement
                break;
            case "paused": 
            break;
            case "inactive": 
            break;
        }
        break;
    case "owner":
        break;
    case "administrator":
        break;
}
十秒萌定你 2024-11-22 20:45:29

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

简而言之:使用 组合 或工厂。 (参见韦斯利·范·奥普多普的回答)。

另外,避免使用字符串参数作为可枚举的:
$viewmode = '访客'
对于这个参数,您必须记住该参数的所有可能值。或者查看函数代码来记住它们。这些值是字符串 - 很容易出现拼写错误。此外,更改功能中的值将非常困难,因为此方法的所有调用都将包含硬编码字符串。
使用类常量:

class AdWriter { 
const view_mode_visitor = 1;
...

另外,$adState - 错误的代码,应该是 $ad->state。但使用公共字段也是不好的做法:)

In 8 chapter of this book you can find very detailed answer to your question.

In short: use Composition or Factories. (see answer of Wesley van Opdorp).

Also, avoid using string arguments as enumerable:
$viewmode = 'visitor'
with this argument, you will have to keep in memory all possible values of this argument. Or look into code of function to remember them. And these values are strings - good place for typos. Also, it will be very difficult to change values in feature, because all calls of this method will contain hardcoded strings.
Use class-constants:

class AdWriter { 
const view_mode_visitor = 1;
...

Also, $adState - wrong code, should be $ad->state. But using public fields it's bad practice too :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文