I've got quite a few POPO's (Plain Old PHP Objects) in my codebase, some of which contain in excess of 30 fields. Some of these objects have many required fields, as well as many optional fields (some of which set defaults.)
Here's a simplified version of one of these classes:
Class POPO {
private $required;
private $alsoRequired;
private $defaultSet = 100;
private $optional;
private $alsoOptional;
public function __construct() {
//some constructor code
}
public function setRequired($required) {
//validate here
$this->required = $required;
}
//other setters
...
}
My question is about best practices. I figure for instanciating the object and setting the values, I have two options:
I could create a constructor that contained default values for non required fields, and use setters for the optional stuff:
public function __construct( $required, $alsoRequired ) { $this->setRequired(1); $this->setAlsoRequired(2); } $POPO1 = new POPO(1,2); //to instanciate new object w/ only required fields. $POPO1->setOptional(3); //to set optional fields
I could create a constructor that contained all fields, using optional parameters:
public function __construct( $required, $alsoRequired, $optional = null, $alsoOptional = null ) { $this->setRequired($required); $this->setAlsoRequired($alsoRequired); $this->setOptional($optional); $this->setAlsoOptional($alsoOptional); } $POPO1 = newPOPO(1,2); //instanciate new object w/ only required fields. $POPO2 = newPOPO(1,2,3,4); //instanciate object w/ optional fields.
This gets confusing when adding or removing params from the class. Every instance where the class is used has to be updated. The same is true for option 1, but to a lesser extent.
A thrid option occured to me to have a no param constructor and use setters for everything, but this would allow the object to be in an invalid state.
So my question is, which of these two options is the better way?
Maybe there is another better way I'm not thinking of?
How about handling default values? Should that be done only via setter?