2013-06-25 5 views
0

У меня есть несколько таблиц, настроенных в Propel, с генерируемыми статическими классами 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]; 
} 

Как вы можете видеть, что я успел написать фабричный метод для объекта строки, но я не мог найти способ сделать то же самое для статических классов. Другими словами, я хотел бы иметь доступ к динамическим статическим классам, а не к уродливому обходному пути.

Любые идеи?

спасибо :)

ответ

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

+0

Спасибо за ваш ответ, у меня есть вопрос: если peer_for - это метод, определенный в объекте, как его назвать? Может быть, вот так ?: $ peer = $ ($ obj-> peer_for ($ type)) – fstab

1

Вы должны быть в состоянии использовать behaviors, чтобы добиться того, что вы пытаетесь сделать. Вы можете использовать поведение для добавления настраиваемого кода в сгенерированные одноранговые объекты. См. here.

Среди прочего, ваши модели поведения могут реализовать следующие методы:

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

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