推动对等静态类:如何避免编写重复的代码?

时间:2013-06-25 09:38:40

标签: php static-methods factory propel anti-patterns

我在Propel中配置了一些表,生成了Peer静态类。

我的问题是我需要在不同但相似的表上执行相同的搜索操作。这些表具有不同的Peer类,因为它是Propel的工作方式。这种情况导致有关在这些表上执行的查询的重复代码。

我想知道是否有一些构造(避免使用函数eval)在这种情况下可能对我有帮助;我真的想避免编写重复的代码,只对不同的静态Peer类执行相同的调用。

我正在编写的类(非常长)方法的示例代码片段:

$criteria = new Criteria();
$criteria->add(FoobarPeer::CONTRACTNR,$data['contractnr']);
$result = FoobarPeer::doSelect($criteria);
if(count($result) > 1){
  throw new FoobarException("status: more than one row with the specified contractnr.");
}
if(count($result) == 0){
  // no object with given contractnr. Create new one.
  $obj = $this->factory->createORM("foobar");
  $obj->setCreatedAt(time());
} else {
  // use and update existing object.
  $obj = $result[0];
}

正如您所看到的,我设法为行对象编写了一个工厂方法,但我找不到对静态类执行相同操作的方法。换句话说,我希望能够动态访问静态类,而不是一种丑陋的解决方法。

有什么想法吗?

谢谢:)

2 个答案:

答案 0 :(得分:1)

我不确定我是否完全明白你在问什么,但这是我想要的想法的解决方案:

function orm_for($type) {
    return strtolower($type);
}

function peer_for($type) {
    return ucfirst($type)."Peer";
}

function exception_for($type) {
    return ucfirst($type)."Exception";
}

function query($type, $data) {
    $peer = $peer_for($type);
    $exception = $exception_for($type);
    $obj = null;
    $criteria = new Criteria();
    $criteria->add($peer::CONTRACTNR, $data["contractnr"]);
    $result = $peer::doSelect($criteria);
    if(count($result) > 1) {
        throw new $exception("status: more than one row with the specified contractnr.");
    } else if(count($result) == 0) {
        $obj = $this->factory->createORM(orm_for($type));
        $obj->setCreatedAt(time());
    } else {
        $obj = $result[0];
    }
}

我认为代码是不言自明的。让我知道我是否正确解释了你的问题。

一个实例(只是一个POC)可以是found here

答案 1 :(得分:1)

您应该可以使用behaviors来实现您的目标。您可以使用行为将自定义代码添加到生成的对等对象。请参阅here

除此之外,您的行为可以实现以下方法:

staticAttributes()   // add static attributes to the peer class
staticMethods()      // add static methods to the peer class

您应该能够使用这些来向同行添加您想要的代码。您只需要担心编写一次代码。 Propel将在代码生成过程中复制代码,但这不应该太过关注,因为很多生成的内容都是重复的。至少复制只能由自动化过程引入。