2016-03-12 65 views
2

我寫了下面的代碼行:我可以使用哪些編碼或設計模式來執行所需的方法調用順序?

$this->validate($group); 

$this->em->persist($group); 
$this->em->flush(); 

法「驗證」會當$組無效拋出異常。問題是,它似乎有點「脆弱」。如果其他開發人員更改了此代碼,可能他會意外移動驗證方法,並且實體管理器會將該對象保存到數據庫中而不驗證它。

你認爲以下幾行代碼更好嗎?還是我只是在推翻它?

$validGroup = $this->validate($group); 

$this->em->persist($validGroup); 
$this->em->flush(); 

是否有任何驗證模式?

+0

編寫驗證被稱爲堅持 – dpolivaev

+0

之前以及明顯的測試將發現它,但我們說的測試是不是一種選擇測試檢查。 – EnchanterIO

回答

1

我會驗證在persist裏面,這樣就不可能持續一個未驗證的對象。如果em是第三方代碼,並且您不想更改它,請將em包裝在您自己的對象中,該對象在寫入數據庫之前進行驗證並在任何地方使用。

設計em或包裝器有幾個選項,以便您只需編寫一次,並可在程序中的任意位置使用單個實例。你可以是

  • 給對象持續驗證自己的責任,例如,要求所有持久對象有一個is_valid方法。 em或者你的包裝會要求對象驗證自己並在對象無效時拋出異常。這可能是最好的解決方案,如果你能夠將行爲添加到可持久對象,因爲它將有效性的想法放在與數據相同的位置。

  • em或者你的包裝檢測對象的類型,查找(在註冊表中或通過命名約定)知道如何驗證該類型對象的驗證器對象,要求驗證器驗證持久對象,並且如果對象無效則再次引發異常。這更復雜一些,但如果驗證足夠複雜以適合單獨的對象,或者如果您無法將行爲添加到可持久對象時,可能會有所幫助。

+0

這不會導致一種情況,我需要一個em包裝器來保存每個我想要保存和驗證的對象類型? – EnchanterIO

+0

我擴大了我的回答,討論了兩個沒有這個問題的驗證策略。 –

+0

第二種選擇似乎更好我會將它標記爲答案,即使我很好奇如何解決它,而不會增加任何複雜性。假設我有一個不太常見的方法,只需要:methodThatHaveToBeCalledFirst()和methodThatHaveToBeCalledSecond()...你做了什麼(不增加複雜性)來避免這種情況? (並且都返回void) – EnchanterIO

0

這個問題涉及到界面設計中一個非常重要和重要的問題。問題是「未聲明的排序」,即方法調用的順序是隱含的和未聲明的。這是很多問題和困惑的來源。

重構它有兩種方法(至少)。兩者已經在上面提供了,我只是對它們進行了總結。

  1. 使用一個方法調用的結果作爲另一個調用的輸入(如OP所做的那樣)。這確保了秩序。當多次使用第一個方法調用的結果時它是適用和有用的。
  2. 調用第二種方法中的第一種方法(反之亦然)。這也將解決問題,因爲界面的用戶必須調用單個方法。
1

Template Pattern適合這個問題。

在模板模式中,抽象類公開定義的方式/模板以執行其方法。它的子類可以根據需要覆蓋方法實現,但是調用的方式與抽象類定義的相同。此模式屬於行爲模式類別。

abstract class MyTemplate{ 
    void myPersist(){ 
     validate(); 
     persist(); 
     flush(); 
} 
相關問題