2015-04-03 2 views
0

Я в настоящее время изучаю структуру и в ней я кодирую Сервис. сама Служба имеет все большее число методов (что не так уж плохо, потому что это, ну, Сервис). беспокойство происходит от устройства сопоставления, которое Служба использует для перевода данных БД в объекты Домен, поскольку этот класс растет в том, что мне кажется неудобным (для каждого метода службы требуется не менее 2 методов Mapper и свойство (одно для получения данных, одно для сопоставления их и свойство для SQL).Менеджер объектов домена?

так что мой вопрос будет, если это рекомендуется сделать класс сопоставителя для каждого метода службы (например, с помощью Factory)?

так, это класс в вопросе :

<?php 

import('sites::foo::biz', 'Held'); 
import('sites::foo::biz', 'Attribut'); 
import('sites::foo::biz', 'Generierung'); 
import('sites::foo::biz', 'Talent'); 
import('sites::foo::biz', 'Kampftalent'); 

class HeldenblattMapper extends APFObject 
{ 
    const SQL_GET_HELD = <<<SQL 
    SELECT 
     name, 
     geschlecht, 
     groesse, 
     gewicht, 
     tsatag, 
     haare, 
     augen, 
     aussehen, 
     stand, 
     titel, 
     SO, 
     hintergrund, 
     AP_frei AS freieAP, 
     AP_gesamt AS alleAP 
    FROM 
     helden 
    WHERE 
     id = ? 
    ; 
SQL; 
    const SQL_GET_ATTR = <<<SQL 
    SELECT 
     Attribut, 
     Wert 
    FROM 
     held_attribute 
    WHERE 
     HeldenID = ? 
    ; 
SQL; 

    const SQL_GET_TALENTE = <<<SQL 
    SELECT 
     Talent, 
     Probe, 
     Attribute, 
     Wert, 
     Kategorie 
    FROM 
     held_talente 
    WHERE 
     HeldenID = ? AND Kategorie = ? 
    ORDER BY 
     Kategorie, Talent 
    ; 
SQL; 

    const SQL_GET_RKP = <<<SQL 
    SELECT 
     RKP, 
     Typ 
    FROM 
     held_rkp 
    WHERE 
     HeldenID = ? AND pri_sec = ? 
    ; 
SQL; 

    const SQL_GET_KAMPF = <<<SQL 
    SELECT 
     Talent, 
     Spezialisierung, 
     AT_PA, 
     Wert, 
     Kategorie, 
     Attacke(HeldenID) AS AT, 
     Parade(HeldenID) AS PA, 
     Fernkampf(HeldenID) AS FK 
    FROM 
     held_kampftalente 
    WHERE 
     HeldenID = ? AND Kategorie = ? 
    ORDER BY 
     Kategorie DESC, Talent ASC 
    ; 
SQL; 

    public function getHeld($id) 
    { 
     $PDOHeld = $this->getPDOById(self::SQL_GET_HELD, $id); 
     return $this->mapPDOHeld2DomainObject($PDOHeld); 
    } 

    public function getAttributeByHeld($id) 
    { 
     $PDOAttr = $this->getPDOById(self::SQL_GET_ATTR, $id); 
     return $this->mapPDOAttribute2DomainObjects($PDOAttr); 
    } 

    public function getRKPByHeld($id) 
    { 
     $sql = 'SELECT RKP FROM held_rkp WHERE HeldenID = ? AND Typ = ? ORDER BY pri_sec ASC;'; 
     $rkp = $this->getPDOConnection()->prepareStatement($sql); 
     $rkp->bindParam(1, $id, PDO::PARAM_INT); 
     $rkp->bindParam(2, $typ, PDO::PARAM_STR); 

     $arr = array(); 
     $types = array('Rasse', 'Kultur', 'Profession'); 
     foreach ($types as $typ) 
     { 
      $rkp->execute(); 
      $arr[$typ] = $this->mapPDORKP2DomainObject($rkp); 
     } 
     return $arr; 
    } 

    public function getTalenteByHeld($id) 
    { 
     $sql = 'SELECT DISTINCT Kategorie FROM held_talente WHERE HeldenID = ?'; 
     $PDOKat = $this->getPDOById($sql, $id); 
     $PDOKat->setFetchMode(PDO::FETCH_COLUMN, 0); 

     $PDOTal = $this->getPDOConnection()->prepareStatement(self::SQL_GET_TALENTE); 
     $PDOTal->bindParam(1, $id, PDO::PARAM_INT); 
     $PDOTal->bindParam(2, $kat, PDO::PARAM_STR); 

     $arr = array(); 
     foreach ($PDOKat as $kat) 
     { 
      $PDOTal->execute(); 
      $arr[$kat] = $this->mapPDOTalente2DomainObjects($PDOTal); 
     } 
     return $arr; 
    } 

    public function getKampftalenteByHeld($id) 
    { 
     $sql = 'SELECT DISTINCT Kategorie FROM held_kampftalente WHERE HeldenID = ?'; 
     $PDOKat = $this->getPDOById($sql, $id); 
     $PDOKat->setFetchMode(PDO::FETCH_COLUMN, 0); 

     $PDOTal = $this->getPDOConnection()->prepareStatement(self::SQL_GET_KAMPF); 
     $PDOTal->bindParam(1, $id, PDO::PARAM_INT); 
     $PDOTal->bindParam(2, $kat, PDO::PARAM_STR); 

     $arr = array(); 
     foreach ($PDOKat as $kat) 
     { 
      $PDOTal->execute(); 
      $arr[$kat] = $this->mapPDOKampf2DomainObjects($PDOTal); 
     } 
     return $arr; 
    } 

    private function mapPDOHeld2DomainObject(PDOStatement $ps) 
    { 
     $row = $ps->fetch(PDO::FETCH_ASSOC); 
     if (!$row) 
     { 
      throw new DomainException('No Character data found.'); 
     } 
     $held = new Held(); 
     $held->setName($row['name']); 
     $held->setGeschlecht($row['geschlecht']); 
     $held->setAlleAP($row['alleAP']); 
     $held->setFreieAP($row['freieAP']); 

     return $held; 
    } 

    private function mapPDOAttribute2DomainObjects(PDOStatement $ps) 
    { 
     $ps->setFetchMode(PDO::FETCH_ASSOC); 
     $arr = array(); 
     foreach ($ps as $row) 
     { 
      $attribut = new Attribut(); 
      $attribut->setName($row['Attribut']); 
      $attribut->setWert($row['Wert']); 
      $arr[] = $attribut; 
     } 
     return $arr; 
    } 

    private function mapPDORKP2DomainObject(PDOStatement $ps) 
    { 
     $rkp = new Generierung(); 
     $rkp->setRKPName($ps->fetchColumn()); 
     $mod = $ps->fetchColumn(); 
     if ($mod) 
     { 
      $rkp->setModifikation($mod); 
     } 
     return $rkp; 
    } 

    private function mapPDOTalente2DomainObjects(PDOStatement $ps) 
    { 
     $ps->setFetchMode(PDO::FETCH_ASSOC); 
     $arr = array(); 
     foreach ($ps as $row) 
     { 
      $talent = new Talent(); 
      $talent->setName($row['Talent']); 
      $talent->setWert($row['Wert']); 
      $talent->setAttribute($row['Attribute']); 
      $talent->setProbe($row['Probe']); 
      $talent->setTyp($row['Kategorie']); 
      $arr[] = $talent; 
     } 
     return $arr; 
    } 

    private function mapPDOKampf2DomainObjects(PDOStatement $ps) 
    { 
     $ps->setFetchMode(PDO::FETCH_ASSOC); 
     $arr = array(); 
     foreach ($ps as $row) 
     { 
      $talent = new Kampftalent(); 
      $talent->setName($row['Talent']); 
      $talent->setWert($row['Wert']); 
      $talent->setSpezialisierung($row['Spezialisierung']); 
      $talent->setAtPaFromDBValue($row['AT_PA'], '_'); 

      if ('Nahkampf' == $row['Kategorie']) 
      { 
       $at = (int) $row['AT'] + $talent->getAT(); 
       $talent->setAT($at); 
       $pa = (int) $row['PA'] + $talent->getPA(); 
       $talent->setPA($pa); 

      } 
      elseif ('Fernkampf' == $row['Kategorie']) 
      { 
       $fk = (int) $row['FK'] + $talent->getAT(); 
       $talent->setAT($fk); 
      } 
      $arr[] = $talent; 
     } 
     return $arr; 
    } 

    private function getPDOConnection() 
    { 
     $cm = $this->getServiceObject('core::database', 'ConnectionManager'); 
     return $cm->getConnection('PDO'); 
    } 

    private function getPDOById($sql, $id) 
    { 
     $ps = $this->getPDOConnection()->prepareStatement($sql); 
     $ps->bindValue(1, (int) $id, PDO::PARAM_INT); 
     $ps->execute(); 
     return $ps; 
    } 

} 

Сопутствующие услуги

<?php 

class HeldenblattService extends APFObject 
{ 
    private $id; 

    public function init($param) 
    { 
     if (!is_int($param)) 
     { 
      throw new InvalidArgumentException('Cannot create a Character Sheet without a valid Character ID.'); 
     } 
     $this->id = $param; 
    } 

    public function getHeld() 
    { 
     $mapper = $this->getMapper(); 
     return $mapper->getHeld($this->id); 
    } 

    public function heldGetRKP() 
    { 
     $mapper = $this->getMapper(); 
     return $mapper->getRKPByHeld($this->id); 
    } 

    public function heldGetAttribute() 
    { 
     $mapper = $this->getMapper(); 
     return $mapper->getAttributeByHeld($this->id); 
    } 

    public function heldGetTalente() 
    { 
     $mapper = $this->getMapper(); 
     return $mapper->getTalenteByHeld($this->id); 
    } 

    public function heldGetKampf() 
    { 
     $mapper = $this->getMapper(); 
     return $mapper->getKampftalenteByHeld($this->id); 
    } 

    private function getMapper() 
    { 
     return $this->getDIServiceObject(
      'sites::foo::data', 
      'HeldenblattMapper' 
     ); 
    } 
} 

Возможно, похоже, что они делают то же самое, но один из них является бизнес-классом, а другой - классом модели (разделение проблем).

+0

Можете ли вы дать нам еще несколько примеров данных, которые вы моделируете и как их переводили? – Linus

+0

Я отредактировал вопрос с моим кодом –

+0

Я думаю, вам нужно больше советов экспертов – Linus

ответ

0

Я предпочел бы использовать одну услугу с несколькими Mappers, так как реализация сопоставления Domain-DB требует больше кода, который просто вызывает загрузку/сохранение Сервиса.

Если Служба растет (не так уж и много в данный момент), я мог бы подумать о создании пары сервис-картпер для каждого раздела/темы. иначе класс mapper будет легко расширять 500 строк.

+0

Это моя мысль .. – Linus

Смежные вопросы