tags:

views:

409

answers:

6

Hey, I'm a fresh out of college graduate. I'm working on a project that I expect will be ultimately maintained by somebody else. I keep encountering an annoying situation on this project, and that is objects that require many private variables and as a result very long constructors.

Apart from variable naming, there isn't any coding standard enforced. I'm wondering how to deal with the likes of this. Sometimes I fear I will see some of my own code on dailywtf in the future!

I tought about trying to enclose some of these arguements in other classes, but in this situation it doesnt really make sense.

Is this a total non-issue or is it something that should and is easily correctable?

public function __construct($uCode = '', $uName = '', $uTime = '', $uArea = '', $uDomain = '', $uText = '', $uId = '', $uNum = '', $uVideo = 0, $uAudio = 0, $uImage = 0){
+15  A: 

Generally speaking, if you have more than about 4 arguments, you are better off using a temporary object or array instead. Often many of the parameters because optional and this can get pretty awkward and error prone pretty fast. So:

class MyClass {
  public function __construct($options) { ... }
...
}

$o = new MyClass(array(
  'uCode' => 'some value',
  'uText' => 'another value',
));

Compare that to:

$o = new MyClass('some value', '', '', '', '', 'another value');

Notice how the array version only includes what you want to pass.

cletus
+4  A: 

Use builder pattern.. here

http://en.wikipedia.org/wiki/Builder_pattern

StackUnderflow
+6  A: 

I tend to lean towards cletus's solution, but the other alternative is to use set() functions for any values that aren't absolutely necessary to have in the constructor.

e.g., if $uCode and $uName are required, but the rest are optional...

public function __construct($uCode = '', $uName = '') {}
public function setUTime($uTime) {}
public function setUArea($uArea) {}
...

It can sometimes be useful to have your setters return $this, so you can chain commands, like so:

$object = new MyObject($code, $name);
$object->setUTime($time)->setUArea($area)->...;
Frank Farmer
+1, this is often how I do it
Alix Axel
+1, i like this way too
Galen
A: 

If you have too many arguments, it is a sign that your method may be doing too much. Try if you can break the task into many smaller tasks and refactor the method. If that fails, passing in a class with all the parameters should be fine.

Hao Wooi Lim
A: 

You can assign that many parameters to an array and pass that array to your __construct instead so you can only have one array parameter.

marknt15
A: 

you could use magic methods

class abc {

    private $allowed = array(
     'uCode',
     'uId'
    );

    public function __set($name, $value) {
     if (in_array($name, $this->allowed)) {
      $this->$name = $value;
     }
    }

    public function __call($name, $args) {
     if (substr($name, 0, 4) == "set_") {
      $var = substr($name, 4);
      if (in_array($var, $this->allowed)) {
       $this->$var = $args[0];
      }
     }
    }

}

$abc = abc();
$abc->uCode = 123;
$abc->set_uId(123);
Ozzy