2016-09-17 61 views
0

假設正在創建一個新文章,它也有記錄,所以:你將如何組織一個在兩個模型上運行的代碼?

INSERT INTO article VALUES ($name); 
INSERT INTO logs VALUES ($name, GET_LAST_ID()); 

代碼:

class Article 
{ 
    public function add($name) 
    { 
     Sql::exec('INSERT INTO article VALUES ('.$name.')'); 
    } 
} 

class Log 
{ 
    public function add($name) 
    { 
     Sql::exec('INSERT INTO logs VALUES ('.$name.', GET_LAST_ID()); 
    } 
} 
在控制器

$article->add('s'); 
$log->add('s'); 
當然

(除了SQL劫持)它是壞的,它可以隨時重複,所以COPY + PASTE會是。你將如何組織一個新班級?它應該是AddArticleAndLogIt?當然不是。

+1

記錄的這個模型可以通過使用一個過程或觸發器來實現。創建一個觸發器,它將添加與添加的當前文章相同的值到日誌表。有些人反對數據庫中的商業邏輯,但我認爲這可能適合你的情況。 – Phiter

+2

'日誌'僅用於此處還是服務?我會試圖讓一個「日誌記錄」服務獲取一組值並將它們記錄在某處?如果您願意,您可以決定在何處撥打記錄器。 –

+0

@PhiterFernandes,不,對不起,我討厭任何一種「觀察者」模式,這是有氣味和不可預知的/不可預知的代碼的核心 –

回答

1

我會爲這兩個DAL(我不稱他們爲模型)對象創建接口。其中一個實現變體是這個Sql :: ...的東西。然後,我會創建IArticleOperations服務,我接受注入IArticle和ILog實現的方法add。然後我會創建它的實現,其中方法add從DAL對象調用這兩個方法。

我懷疑你的問題可能有點不同。可能是你希望每次添加新業務模型時都記錄日誌(不僅是本文)?

1

我認爲這個問題很難得到正確的答案,因爲它取決於你的喜好(例如你不喜歡觀察者/觸發器)和你的代碼。數據插入器服務將是一個不錯的選擇也類似:

class DataPersister 
{ 
    public function create($table, array $data) 
    { 
     // This of course is a very bad implementation, I would 
     // use placeholders, but it follows the example code you posted. 
     Sql::exec(sprintf(
      'INSERT INTO %s (%s) VALUES (%s)', 
      $table, 
      implode(', ', array_keys($data)), 
      '"' . implode('", "', $data) . '"' 
     )); 

     $this->log($data); 
    } 

    public function log(array $data) 
    { 
     Sql::exec('INSERT INTO logs VALUES (' . $data['name'] . ', GET_LAST_ID()); 
    } 
} 

你會使用這個爲:

$articleData = [ 'name' => 's' ]; 
$persister->create('articles', $articleData); 

$commentData = [ ... ]; 
$persister->create('comments', $commentData); 
相關問題