Я собираюсь попробовать что-то с форматом этого вопроса, и я очень открыт для предложений о лучшем способе справиться с этим.
Я не хотел просто выкидывать кучу кода в вопросе, поэтому я разместил код для класса на refactormycode
.
базовый класс для простой обработки свойств класса
Я думал, что люди могут либо размещать здесь фрагменты кода, либо вносить изменения в refactormycode
и публиковать ссылки на свои рефакторинги. На этом основании я проголосую и приму ответ (при условии, что есть явный «победитель»).
Во всяком случае, для самого класса:
Я вижу много споров о методах класса getter / setter, и лучше ли просто обращаться к простым переменным свойств напрямую, или если каждый класс имеет явные методы get / set, бла-бла-бла. Мне нравится идея иметь явные методы на случай, если вам придется добавить больше логики позже. Тогда вам не нужно изменять код, который использует класс. Однако я ненавижу иметь миллион функций, которые выглядят так:
public function getFirstName()
{
return $this->firstName;
}
public function setFirstName($firstName)
{
return $this->firstName;
}
Теперь я уверен, что я не первый, кто делает это (я надеюсь, что есть лучший способ сделать это, который кто-то может мне предложить).
По сути, класс PropertyHandler имеет магический метод __call. Любые методы, которые проходят через __call, которые начинаются с «get» или «set», затем направляются в функции, которые устанавливают или извлекают значения в ассоциативный массив. Ключ в массиве - это имя вызывающего метода после получения или установки. Таким образом, если в метод __call входит метод «getFirstName», ключ массива - «FirstName».
Мне понравилось использовать __call, потому что он автоматически позаботится о случае, когда для подкласса уже определен метод "getFirstName". У меня сложилось впечатление (и я могу ошибаться), что магические методы __get & __set этого не делают.
Итак, вот пример того, как это будет работать:
class PropTest extends PropertyHandler
{
public function __construct()
{
parent::__construct();
}
}
$props = new PropTest();
$props->setFirstName("Mark");
echo $props->getFirstName();
Обратите внимание, что PropTest на самом деле не имеет методов "setFirstName" или "getFirstName", а также PropertyHandler. Все, что он делает, это манипулирует значениями массива.
В другом случае ваш подкласс уже расширяет что-то еще. Поскольку у вас не может быть истинного множественного наследования в PHP, вы можете сделать так, чтобы ваш подкласс имел экземпляр PropertyHandler в качестве закрытой переменной. Вы должны добавить еще одну функцию, но тогда все будет вести себя точно так же.
class PropTest2
{
private $props;
public function __construct()
{
$this->props = new PropertyHandler();
}
public function __call($method, $arguments)
{
return $this->props->__call($method, $arguments);
}
}
$props2 = new PropTest2();
$props2->setFirstName('Mark');
echo $props2->getFirstName();
Обратите внимание, что у подкласса есть метод __call, который просто передает все в метод PropertyHandler __call.
Другим хорошим аргументом против обработки методов получения и установки таким образом является то, что это действительно затрудняет документирование.
Фактически, в принципе невозможно использовать какой-либо инструмент генерации документов, так как явных методов, которые не документированы, не существует.
Пока я почти отказался от этого подхода. Это было интересное учебное упражнение, но я думаю, что оно приносит слишком много ясности.