How do i deal with multiple contructor arguments or class variables?

我们两清 提交于 2019-12-25 06:35:22

问题


How do I know what to load in a constructor and what to set using the set methods later on?

For example, I have a question class which most of the time will call the following vars:

protected $question;
protected $content;
protected $creator;
protected $date_added;
protected $id;
protected $category;

At the moment I have it so only the bare essentials $id, $question, and $content are set in the constructor so I don't start building up a huge list of constructor arguments. This however, means that when I make a new question object elsewhere, I have to set the other properties of that object straight after meaning 'setter code' getting duplicated all over the place.

Should I just pass them all into the constructor right away, do it the way I'm doing it already, or is there a better solution that I'm missing? Thanks.


回答1:


Depending on the language you can have multiple constructors for any one class.




回答2:


You could use an array as the parameter to the constructor or setter method.

Just example:

public function __construct($attributes = array()) {
  $this->setAttributes($attributes);
}  

public function setAttributes($attributes = array()) {
  foreach ($attributes as $key => $value) {
    $this->{$key} = $value;
  }
}



回答3:


PHP doesn't support traditional constructor overloading (as other OO languages do). An option is to pass an array of arguments into the constructor:

public function __construct($params)
{

}

// calling it
$arr = array(
    'question' => 'some question',
    'content' => ' some content'
    ...
);
$q = new Question($arr);

Using that, you're free to pass a variable number of arguments and there is no dependency on the order of arguments. Also within the constructor, you can set defaults so if a variable is not present, use the default instead.




回答4:


I would pass an array to the constructor with the values I want to set.

public function __construct(array $values = null)
{
    if (is_array($values)) {
        $this->setValues($values);
    }
}

Then you need a method setValues to dynamicly set the values.

public function setValues(array $values)
{
    $methods = get_class_methods($this);
    foreach ($values as $key => $value) {
        $method = 'set' . ucfirst($key);
        if (in_array($method, $methods)) {
            $this->$method($value);
        }
    }
    return $this;
}

For this to work you need setter methods for your properties like setQuestion($value) etc.




回答5:


A fluent interface is another solution.

class Foo {
  protected $question;
  protected $content;
  protected $creator;
  ...

  public function setQuestion($value) {
    $this->question = $value;
    return $this;
  }

  public function setContent($value) {
    $this->content = $value;
    return $this;
  }

  public function setCreator($value) {
    $this->creator = $value;
    return $this;
  }

  ...
}

$bar = new Foo();
$bar
  ->setQuestion('something')
  ->setContent('something else')
  ->setCreator('someone');

Or use inheritance...

class Foo {
  protected $stuff;

  public function __construct($stuff) {
    $this->stuff = $stuff;
  }

  ...
 }

class bar extends Foo {
  protected $moreStuff;

  public function __construct($stuff, $moreStuff) {
    parent::__construct($stuff);
    $this->moreStuff = $moreStuff;
  }

  ...
}

Or use optional parameters...

class Foo {
  protected $stuff;
  protected $moreStuff;

  public function __construct($stuff, $moreStuff = null) {
    $this->stuff = $stuff;
    $this->moreStuff = $moreStuff;
  }

  ...
}

In any case, there are many good solutions. Please dont use a single array as params or func_get_args or _get/_set/__call magic, unless you have a really good reason to do so, and have exhausted all other options.



来源:https://stackoverflow.com/questions/14937416/how-do-i-deal-with-multiple-contructor-arguments-or-class-variables

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!