Волшебные добытчики и сеттеры в 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;
    }
}
Author: Community, 2013-03-16

5 answers

Я согласен с другими людьми на этой странице, что это плохая практика, и вам следует придерживаться старых добытчиков и сеттеров, а не магических методов. Как только вам понадобится проверка или другие вычисления в средствах доступа/мутаторах, ваш переключатель/корпус взорвется. Это беспорядок для поддержания и не совсем благоприятный для наследования. Дочерний класс с магическими методами технически перезаписывает магический метод родителя.

Однако это можно сделать, изменив шаблоны кода с помощью Шаблона кода Редактор EA.

Цитата из Руководство пользователя Enterprise Architect по шаблонам кода:

Шаблоны кода позволяют настраивать генерацию кода на существующих языках. Например:

  • Измените заголовки файлов, созданные при создании новых файлов
  • Измените стиль сгенерированного кода (например, отступ или положение скобок), чтобы он соответствовал требуемым стандартам кодирования
  • Обрабатывайте определенные стереотипы для создания таких вещей, как специализированные методические органы и дополнительные методы.

И далее:

Шаблоны базового кода Enterprise Architect определяют преобразование элементов UML в различные части данного языка программирования. Шаблоны написаны в виде простого текста с синтаксисом, который разделяет некоторые аспекты как языков разметки, так и языков сценариев.

Вот пример изображения редактора кода с некоторым шаблоном, загруженным в это:

Enterprise Architect Code Template Editor

Я не знаком ни с редактором, ни с языком шаблонов, который они используют, поэтому я не могу предоставить вам рабочий пример. Но я думаю, что вы можете понять это оттуда, если вы действительно хотите изменить шаблон.

 5
Author: Gordon, 2013-03-30 18:44:37

На самом деле это не ответ, но вам следует подумать, хотите ли вы, чтобы это было сделано таким образом. Это не принесет никаких преимуществ, но вызовет проблемы с функциями завершения кода IDE и фактически усложнит обслуживание кода. На мой взгляд, magic __get/__set следует использовать только для динамических свойств, в противном случае используйте отдельные методы set/get или используйте общедоступные свойства. Этот ответ в значительной степени подводит итог.

Если вы все еще хотите пойти по этому пути, я бы рекомендовал проще подход.

 6
Author: Furgas, 2017-05-23 11:45:00

Вы можете реализовать универсальный магический геттер/сеттер следующим образом:

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;
}

Но имейте это в виду:

Это действительно плохой шаблон проектирования для вашего кода (даже если это СУХАЯ практика)

Кроме того, этот код строго эквивалентен тому, чтобы сделать все ваши свойства общедоступными, и у вас не будет накладных расходов из-за магических методов. Приятно то, что если вы хотите выполнить одинаковые проверки на вменяемость для каждого сеттера, вы можете сделать это там.

 3
Author: Mathieu Amiot, 2013-03-30 18:18:03

Я хотел бы использовать магические методы __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__
 0
Author: Yang, 2013-04-03 19:26:37

Я не знаю, используете ли вы 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 не будет подсказывать вам имена свойств (из-за пределов класса), и вам придется вводить их все долго. Использование геттеров и сеттеров (, которые являются общедоступными методами, предоставляющими Вам доступ к частным или защищенным свойствам ) Вы можете использовать подсказки кода и ускорить процесс разработки, используя современные принципы ООП.

 -1
Author: shadyyx, 2013-04-02 08:50:03