2015-10-20 72 views
0

我需要一些關於MVC設計的幫助。 MVC和CODEIGNITER的大部分教程都是在控制器中進行輸入驗證。這是一個好習慣嗎?
假設我們實現REST或SOAP API,那麼我們將擁有不同的控制器,並且對於所有這些控制器,我需要複製我的代碼。稍後,如果任何驗證規則發生更改,它將會波及所有控制器。是不是所有的驗證都應該在Model而不是Controller中?
我還想問一件事。當我試圖保持我的功能儘可能緊密時,我正在獲得模型和控制器功能之間的一對一關係。沒關係,或者我做錯了什麼?MVC中的輸入驗證

回答

0
  1. 關於在控制器中進行輸入驗證 Ans。是的,這是大多數MVC普遍接受的做法。但是,在過去幾年中,由於AJAX框架的出現以及JavaScript的更多采用,許多UI驗證都是在UI本身完成的(稱爲客戶端驗證)。這些通常顯示爲JavaScript警報框,並且不允許用戶繼續前進,除非他修復了這些錯誤。所以,我會說控制器/視圖助手實際上是驗證完成的地方,但您應該考慮在可行的情況下進行客戶端驗證。它還可以節省您前往服務器的時間。

  2. 如果您公開的功能與SOAP/REST Ans相同。現在,您可以註釋相同的控制器方法,使其作爲Web服務端點工作。因此,您的控制器可以同時處理基於Web的請求和SOAP/REST請求。 但請注意一點 - 你的形態豆/支撐豆應該設計得很好。我已經看到了代碼,其中hibernate模型對象被用作表單支持對象。由於hibernate模型對象可能有許多鏈接的實體,並且在請求/響應中以非常複雜的xml結構結束,所以當您從表單支持對象中生成WSDL時,這會非常棘手。 但是,如果你設計的支持bean是細粒度的,即沒有複雜的對象,那麼你應該放心使用現有的控制器/控制器方法作爲SOAP/REST的Web服務端點。

  3. 關於模型層內的驗證 Ans。您可以使用此經驗法則來確定在何處放置其驗證 -
    • 業務驗證應在模型/服務發生
    • 複雜的客戶端驗證,這是不是在客戶端是可行的,應在控制器/視圖助手發生
    • UI驗證(格式化/空檢查)應通過客戶端/ JavaScript的驗證
  4. 關於控制器和模型/服務 答的功能之間以一對一的關係發生。沒關係。只要記住有一個控制器方法與其各自的模型方法交談。如果需要多個模型來爲請求提供服務,那麼該模型方法應該充當來自多個模型的信息聚合器,即控制器應該聯繫其主要模型,並且主要模型應該聯繫其他模型。
+0

我明白了你的觀點,但我很少有混淆。我們可以依靠客戶端驗證嗎?客戶端可以通過禁用JavaScript或通過使用http請求標頭來繞過驗證。如果一個模型調用另一個模型,那麼不會違反SOC,因爲模型的凝聚力會降低?你能否給我提供一些鏈接或例子,描述使控制器與多個模型交談的缺陷。對於提出太多問題抱歉。 –

+0

是的,您可以依靠客戶端驗證。基本上只有當所有客戶端驗證通過時才提交表單。如果你看看所有主要的網站,他們嚴重依賴於JavaScript。只有少數人擁有非JavaScript版本。關於模型調用模型,它是業務邏輯的服務調用服務的普遍接受的實踐。我不是說DAO打電話給DAO。應僅從各自的服務中調用DAO。最後,我曾在許多基於網絡的項目中工作,我的答案是基於此。我沒有參考網站的手頭清單。 –

+0

@KrrishRaj客戶端驗證可以依賴,但可能不會,也可能不應該完全消除對後端驗證的需求。模型調用模型,IMO顯然違反了SOC。另一方面,有一個控制器使用多個模型在我看來是你如何創建SOC。 CodeIgniter將允許您在另一個模型中加載模型。最容易陷入這種方式的陷阱是一個依賴性問題。特別是,循環引用都很容易構建。 – DFriend

0

這是一個很好的做法嗎?根據我的經驗是的。

有一點要記住,任何給定的控制器都可以顯示多個不同的頁面。例如,考慮一個「儀表板」,它可能有多個任務,每個任務都需要自己的頁面。

粗略僞codeish「儀表板」控制器可能是這樣的:

class Dashboard extends CI_Controller { 
    public function __construct(){ 
    parent :: __construct(); 
    $this->load->helper(array('form', 'url')); 
    $this->load->library('form_validation'); 
    $this->load->model('somemodel_model'); 
    } 
    public function index(){ 
    //displays a task selection page with links to various tasks 
    } 
    public function admins(){ 
    //some kind of interface to display and edit admin level users 
    } 
    public function users(){ 
    //CRUD for dashboard users 
    } 
} 

與此控制器的任務選擇頁面打開與baseurl/dashboard,管理員聯繫與baseurl/dashboard/adminsbaseurl/dashboard/users用戶CRUD頁面。因爲每個這些共享相同的類,所有/許多這些頁面所需的代碼(如驗證)可以在構造函數和/或私有方法中實現。你可能已經知道了這一切。請記住,AJAX響應者也可以使用相同的技術駐留在控制器中。

關於保持驗證規則DRY並緩解更改規則所需的工作CI可以將一組規則存儲在配置文件中,以便在多種情況下輕鬆重複使用。 Read about it.