Enterprise Architect中的魔术吸气剂和制定者

时间:2013-03-16 10:58:20

标签: php uml getter-setter enterprise-architect magic-methods

我正在使用Enterprise Architect制作UML类图并用它生成PHP5代码。使用this,可以为属性创建getter和setter,在代码中看起来像这样(只显示相关的行):

private $id;

public function getId()
{
    return $this->id;
}

/**
 * 
 * @param newVal
 */
public function setId($newVal)
{
    $this->id = $newVal;
}

我想使用魔术方法__get($property)__set($property, $value)代替每个属性的单独方法。是否可能,如果可能,怎么样?

对于getter来说,它看起来像这样:

public function __get($property)
{
    switch ($property) {
        case 'id': return $this->id; break;
        default: return null;
    }
}

5 个答案:

答案 0 :(得分:6)

不是真的答案,但你应该考虑是否要这样做。这不会带来任何好处,但会导致IDE代码完成功能出现问题,实际上会使代码维护更加困难。在我看来,magic __get / __ set应仅用于动态属性,否则使用单独的set / get方法或使用公共属性。 This answer几乎总结了它。

如果你还想走这条路,我会推荐simpler approach

答案 1 :(得分:5)

我同意本页面上的其他人认为这是不好的做法,你应该坚持使用普通的吸尘器和魔术方法。一旦您需要在访问器/更改器中进行验证或其他计算,您的开关/案例就会爆炸。这是一个混乱的维护,而不是完全友好的继承。使用魔术方法的子类在技术上会覆盖父级的魔法。

但是,您可以通过使用EA的代码模板编辑器修改代码模板来实现这一点。

引自Enterprise Architect User Guide on Code Templates

  

代码模板使您可以自定义现有语言的代码生成。例如:

     
      
  • 修改生成新文件时创建的文件标题
  •   
  • 更改生成代码的样式(例如缩进或支撑位置)以匹配所需的编码标准
  •   
  • 处理特定的构造型以生成专门的方法体和额外的方法。
  •   

并进一步:

  

Enterprise Architect的基本代码模板指定从UML元素到给定编程语言的各个部分的转换。模板以纯文本形式编写,其语法与标记语言和脚本语言的某些方面共享。

以下是代码编辑器的示例图片,其中加载了一些模板:

Enterprise Architect Code Template Editor

我不熟悉编辑器或他们使用的模板语言,所以我无法为您提供一个工作示例。但是如果你真的想修改模板,我想你可以从那里弄明白。

答案 2 :(得分:3)

你可以像这样实现一个通用的魔法getter / setter:

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

但要牢记这一点:

这是代码真正错误的设计模式(即使它是符合DRY的做法)

此外,此代码完全等同于将所有属性公开,并且由于魔术方法,您不会有开销。 好消息是如果你想对每个setter执行相同的健全性检查,你可以在那里进行。

答案 3 :(得分:0)

  

我想使用魔术方法__get($ property)和   __set($ property,$ value)而不是每个属性的单独方法。有可能,如果可能,怎么样?

不应该定义每个属性。一个简单的数组容器对他们来说足够了。所以,这正是您正在寻找的:

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__

答案 4 :(得分:-1)

我不知道您是使用IDE进行开发还是使用纯记事本。因为你问这类问题我猜它是记事本。然后我建议您尝试使用许多免费IDE中的一个(我使用NetBeans多年,其他人也可能对Eclipse感到满意)。

如果您正在使用EA并且正在使用类模型,我猜您正在认真对待OOP。如果是这样,您应该严格定义属性可见性,例如, Zend Framework 2忘记了public property可见性(结果还包括staticpublic static属性)。然后你得到的属性为privateprotected,并且地球上需要吸气剂/定位器。

现在,如果您使用魔术__get() / __set()方法,您将如何调试代码?一个人如何通过属性\One\Two\Three\Four来讲述课程\First\Second\Third::$bang中会发生什么?怎么设置?为什么我得到这个值而不是另一个呢?

另一方面 - 当使用遵循属性可见性的现代IDE时,请考虑这个类:

Class A
{
    private $foo;
    private $bar;

    protected $foobar;

    public function __get()
    {
        ...
    }

    public function __set()
    {
        ...
    }
}

没有制定者或吸气者。如果您正在编写代码,您的IDE将不会提示您属性的名称(来自课外),您必须长时间键入它们。使用getter和setter(是公共方法,允许您访问私有或受保护的属性)您可以使用代码提示并在使用现代OOP原则的同时进行开发过程。