首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >通过数组定义类选项是一种糟糕的做法吗?

通过数组定义类选项是一种糟糕的做法吗?
EN

Stack Overflow用户
提问于 2010-12-28 22:28:32
回答 7查看 2K关注 0票数 6

当我们查看Javascript框架(如Dojo、Mootools、jQuery、JS原型等)时,我们看到选项通常是通过如下数组定义的:

代码语言:javascript
运行
复制
dosomething('mainsetting',{duration:3,allowothers:true,astring:'hello'});

在编写PHP类时实现相同的想法是一种糟糕的做法吗?

一个例子:

代码语言:javascript
运行
复制
class Hello {

    private $message = '';
    private $person = '';


    public function __construct($options) {

        if(isset($options['message'])) $this->message = $message;
        if(isset($options['person'])) $this->person = $person;
    }


    public function talk() {

        echo $this->person . ' says: ' . $this->message;
    }
}

常规方法:

代码语言:javascript
运行
复制
class Hello {

    private $message = '';
    private $person = '';


    public function __construct() {}


    public function setmessage($message) {

        $this->message = $message;
    }


    public function setperson($person) {

        $this->person = $person;
    }


    public function talk() {

        echo $this->person . ' says: ' . $this->message;
    }
}

第一个例子的优点是,您可以传递任意多的选项,类只会提取它需要的选项。

例如,当从JSON文件中提取选项时,这是很方便的:

代码语言:javascript
运行
复制
$options = json_decode($options);
$hello = new Hello($options);

我就是这样做的:

代码语言:javascript
运行
复制
$options = json_decode($options);
$hello = new Hello();

if(isset($options['message'])) $hello->setmessage($options['message']);
if(isset($options['person'])) $hello->setperson($options['person']);

这种模式有名字吗?你认为这是一种不好的做法吗?

为了保持简单,我在示例中保留了验证等内容。

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2010-12-28 22:32:04

有好的方面也有坏的方面。

The good:

  • 不需要多个方法签名(即重载,支持)
  • 与前一点保持一致:方法可以使用任意顺序的参数调用。
  • 可以动态生成参数,而不需要指定将出现的每个参数(例如:根据用户输入动态创建参数数组并将其传递给函数)
  • 不需要像setNamesetThissetThat等“样板”方法,尽管您可能仍然希望将它们包括在内。
  • 默认值可以在函数体中定义,而不是在签名中定义(jQuery经常使用这种模式)。它们经常将传递给具有默认值数组的方法的选项$.extend。在您的例子中,您将使用array_merge())

The bad:

  • 除非您正确地为每个选项做广告,否则您的类可能更难使用,因为很少有人知道支持哪些选项。
  • 当您提前知道需要传递的参数数组时,这是创建参数数组的又一步
  • 对于用户来说,默认值的存在并不总是显而易见的,除非提供了文档或者他们可以访问源代码。

在我看来,这是一种很棒的技术。我最喜欢的一点是,您不需要提供具有不同签名的重载方法,而且签名也不是固定的。

票数 12
EN

Stack Overflow用户

发布于 2010-12-28 22:38:21

这种方法没有什么问题,特别是当您有很多需要传递给构造函数的参数的时候。这还允许您为它们设置默认值,并在构造函数中为它们设置array_merge() (有点像所有的jQuery插件)。

代码语言:javascript
运行
复制
protected $default_params = array(
    'option1' => 'default_value'
);
public function __construct($params = array()) {
    $this->params = array_merge($this->default_params, $params);
}

如果您想要这种“模式”的活生生的例子,请查看symfony框架,他们几乎在任何地方都使用它:这里是sfValidatorBase构造函数的一个例子

票数 3
EN

Stack Overflow用户

发布于 2010-12-28 22:42:09

当你给出参数名时,它被称为“命名符号”v.s。“位置表示法”,其中的参数必须在一个特定的顺序。

在PHP中,您可以传递一个"options“参数,以提供与其他语言(如Python)相同的效果,在那里您可以使用真正的命名符号。这并不是一种糟糕的做法,但通常是在有充分理由这样做的地方进行的(例如,在您的例子中,或者在存在大量争论且不需要按任何特定顺序设置的情况下)。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4550046

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档