Волшебные добытчики и сеттеры в Enterprise Architect
Я использую Enterprise Architect для создания диаграммы классов UML и генерации кода PHP5 с ее помощью. Используя это , можно создать геттеры и сеттеры для атрибута, который выглядит так в коде (показаны только соответствующие строки):
private $id;
public function getId()
{
return $this->id;
}
/**
*
* @param newVal
*/
public function setId($newVal)
{
$this->id = $newVal;
}
Я хотел бы использовать магические методы __get($property)
и __set($property, $value)
вместо отдельных методов для каждого свойства. Возможно ли это, и если да, то как?
Это может выглядеть так, для добытчика:
public function __get($property)
{
switch ($property) {
case 'id': return $this->id; break;
default: return null;
}
}
5 answers
Я согласен с другими людьми на этой странице, что это плохая практика, и вам следует придерживаться старых добытчиков и сеттеров, а не магических методов. Как только вам понадобится проверка или другие вычисления в средствах доступа/мутаторах, ваш переключатель/корпус взорвется. Это беспорядок для поддержания и не совсем благоприятный для наследования. Дочерний класс с магическими методами технически перезаписывает магический метод родителя.
Однако это можно сделать, изменив шаблоны кода с помощью Шаблона кода Редактор EA.
Цитата из Руководство пользователя Enterprise Architect по шаблонам кода:
Шаблоны кода позволяют настраивать генерацию кода на существующих языках. Например:
- Измените заголовки файлов, созданные при создании новых файлов
- Измените стиль сгенерированного кода (например, отступ или положение скобок), чтобы он соответствовал требуемым стандартам кодирования
- Обрабатывайте определенные стереотипы для создания таких вещей, как специализированные методические органы и дополнительные методы.
И далее:
Шаблоны базового кода Enterprise Architect определяют преобразование элементов UML в различные части данного языка программирования. Шаблоны написаны в виде простого текста с синтаксисом, который разделяет некоторые аспекты как языков разметки, так и языков сценариев.
Вот пример изображения редактора кода с некоторым шаблоном, загруженным в это:
Я не знаком ни с редактором, ни с языком шаблонов, который они используют, поэтому я не могу предоставить вам рабочий пример. Но я думаю, что вы можете понять это оттуда, если вы действительно хотите изменить шаблон.
На самом деле это не ответ, но вам следует подумать, хотите ли вы, чтобы это было сделано таким образом. Это не принесет никаких преимуществ, но вызовет проблемы с функциями завершения кода IDE и фактически усложнит обслуживание кода. На мой взгляд, magic __get/__set следует использовать только для динамических свойств, в противном случае используйте отдельные методы set/get или используйте общедоступные свойства. Этот ответ в значительной степени подводит итог.
Если вы все еще хотите пойти по этому пути, я бы рекомендовал проще подход.
Вы можете реализовать универсальный магический геттер/сеттер следующим образом:
public function __get($name)
{
if (property_exists($this, $name))
return $this->{$name};
return null;
}
public function __set($name, $value)
{
if (property_exists($this, $name) && true/*Sanity checks here on $value instead of true if you want*/)
$this->{$name} = $value;
}
Но имейте это в виду:
Это действительно плохой шаблон проектирования для вашего кода (даже если это СУХАЯ практика)
Кроме того, этот код строго эквивалентен тому, чтобы сделать все ваши свойства общедоступными, и у вас не будет накладных расходов из-за магических методов. Приятно то, что если вы хотите выполнить одинаковые проверки на вменяемость для каждого сеттера, вы можете сделать это там.
Я хотел бы использовать магические методы __get($property) и __set($свойство, $значение) вместо отдельных методов для каждого свойства. Возможно ли это, и если да, то как?
Тогда вы не должны определять каждое свойство. Для них будет достаточно одного простого контейнера массива. Итак, это именно то, что вы ищете:
class Foo
{
private $container = array();
public function __set($property, $value)
{
$this->container[$property] = $value;
}
public function __get($property)
{
if (array_key_exists($property, $this->container)){
return $this->container[$property];
} else {
trigger_error(sprintf('Undefined property "%s"', $property));
}
}
}
$foo = new Foo();
$foo->bar = "123";
print $foo->bar; // prints 123
$foo->id = "test string";
print $foo->id; // test string
print $foo->nonExistingProp; //issues E_NOTICE
Если вы настаиваете на средствах доступа/модификаторах, то вам нужно только перегрузить их. использование __call()
class Foo
{
private $container = array();
public function __call($method, array $args)
{
$property = substr($method, 3);
if (substr($method, 0, 3) == 'get'){
// getter is being used
if (isset($this->container[$property])){
return $this->container[$property];
}
}
if (substr($method, 0, 3) == 'set'){
//setter is being used
$this->container[$property] = $args[0];
}
}
}
$foo = new Foo();
$foo->setId('__BAR__');
$foo->setStuff('__YEAH__');
print $foo->getId(); // prints __BAR__
print $foo->getStuff(); //prints __YEAH__
Я не знаю, используете ли вы IDE для разработки или чистый блокнот. Поскольку вы задаете такие вопросы, я бы предположил, что это Блокнот. Тогда я бы порекомендовал Вам попробовать одну из многих бесплатных IDE (я использую NetBeans в течение многих лет, другие тоже могут быть довольны Eclipse).
Если Вы используете EA и делаете модели классов, я бы предположил, что вы серьезно относитесь к ООП. Если это так, вы должны строго определить видимость свойств и, например, Zend Framework 2, забыть о public property
видимость (которая также завершает свойство static
или public static
). Тогда вы получите свойства private
или protected
, и потребность в геттерах/сеттерах будет на Земле.
Теперь, если Вы используете магию __get()
/__set()
методы как бы Вы отладили Свой код? Как человек может сказать, что происходит в классе \One\Two\Three\Four
со свойством \First\Second\Third::$bang
? Как это было установлено? Почему я получаю это значение вместо другого?
И с другой стороны - при использовании современной среды разработки, которая следует за видимостью свойств, подумайте об этом класс:
Class A
{
private $foo;
private $bar;
protected $foobar;
public function __get()
{
...
}
public function __set()
{
...
}
}
Без сеттеров или геттеров. Если Вы пишете свой код, ваша среда IDE не будет подсказывать вам имена свойств (из-за пределов класса), и вам придется вводить их все долго. Использование геттеров и сеттеров (, которые являются общедоступными методами, предоставляющими Вам доступ к частным или защищенным свойствам ) Вы можете использовать подсказки кода и ускорить процесс разработки, используя современные принципы ООП.