У меня в кодовой базе довольно много POPO (Plain Old PHP Objects), некоторые из которых содержат более 30 полей. Некоторые из этих объектов имеют много обязательных полей, а также множество необязательных полей (некоторые из которых устанавливают значения по умолчанию).
Вот упрощенная версия одного из этих классов:
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
...
}
Мой вопрос о лучших практиках. Я рассчитываю на создание экземпляра объекта и установку значений, у меня есть два варианта:
Я мог бы создать конструктор, который содержал бы значения по умолчанию для необязательных полей, и использовать установщики для дополнительного материала:
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
Я мог бы создать конструктор, содержащий все поля, используя необязательные параметры:
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.
Это сбивает с толку при добавлении или удалении параметров из класса. Каждый экземпляр, где используется класс, должен быть обновлен. То же самое верно для варианта 1, но в меньшей степени.
Мне выпал вариант thrid, чтобы иметь конструктор без параметров и использовать сеттеры для всего, но это позволило бы объекту находиться в недопустимом состоянии.
Итак, мой вопрос: какой из этих двух вариантов лучше?
Может быть, есть другой лучший способ, о котором я не думаю?
Как насчет обработки значений по умолчанию? Это должно быть сделано только через сеттер?
Это сбивает с толку при добавлении или удалении параметров из класса.
Класс должен быть открыт для расширения, но закрыт для модификации — «О» в «ТВЕРДОМ»
Более чистый подход может быть передать массив конструктору. Вы можете выбрать два отдельных массива — один для обязательных атрибутов, а второй для необязательных.
Дополнительно, несколько конструкторов также могут быть использованы, если требуется.
Других решений пока нет …