Transcript 07. MVC

Model-View-Controller
IDIC
By Cwlin
傳統的開發方式
• 程式不分架構、所有東西寫在一起,沒有明確的規則
傳統的開發方式 (續)
• 在開發小型程式的時候速度較快
• 當程式規模變大時會導致程式難以維護
• 主程式與畫面寫在一起
• 網頁內容調整困難且無法分工
• 主程式與資料庫操作寫在一起
• 資料結構的變動會使得程式必須整個重新檢查、搛寫
MVC
• 從傳統的開發方式當中,我們找到了規則並分類
MVC (續)
• 我們將整個程式分類成三個部份,並明確定義之間互動的關係
• Model
• 負責處理有關資料的操作,如: 資新的新增/修改/刪除和查詢
• View
• 負責處理有關使用者介面該如何呈現,如: HTML
• Controller
• 為主程式負責處理使用者的要求,包含商業邏輯的部份,依需求去
存取 Model,並將結果透過 View 回傳給使用者
MVC 的優點
• 程式與畫面的切割
• 後端開發人員與前端開發人員較易於分工
• 畫面的修改不會影響主程式的運作
• 程式與資料的切割
• 資料結構的變動不會直接影響主程式的運
作
• 減少更換資料庫的轉換成本
• 不同企業採用的資料庫不盡相同
MVC 的互動
Browser
Client
Request/Response
Server
Controller
Generate Page
Access Data
Model
(ezSQL)
Read Data
View
(Smarty)
MVC 互動關係
• Controller-View
• Controller 會將執行動作完的結果傳送給 View,讓 View 產生
畫面以回應給瀏覽器
• Controller-Model
• 當使用者的操作需要讀取或記錄到資料庫時,Controller 便會
透過 Model 去取得資料以便完成動作並將結果寫回資料庫
• View-Model
• 一般來說,Controller 會將執行的結果給 View 產生畫面,但
若不需要經過 Controller 處理的的資訊,View 便可以直接從
Model 取得要顯示的資料
UI 與 MVC
Web Server
Browser
Smarty
Controller
Dispatcher
Event
add
View
add
Request
Main
Program
update
Use
update
delete
Model
EzSQL
UI Component
Action
MVC 的設計
• MVC 建立在物件導向程式設計的基礎上
• Model-View-Controller 三者可視為不同物件的類型(Class)
• 在設計時會依據三者所負責的功能定義出物件的雛形,在
實際開發時可以繼承使用
Controller 的設計
• Controller 需要接收瀏覽器的請求,請求會透過表單的
GET 與 POST 將執行所需的資料傳送給 Controller 做處理
• Controller 負責程式的商業邏輯,在執行時的防呆、規
則、計算方式通通會在 Controller 做處理
abstract class Controller {
public function getAction() {
return $_GET['action'];
}
abstract function run();
}
Controller 的設計 (續)
class MemberController extends Controller
{
public function run()
{
$actionListener = null;
$action = $this->getAction();
switch($action){
case 'ShowInsertPage':
$actionListener = new ShowInsertPageAction();
break;
case 'DoInsert':
$actionListener = new DoInsertAction();
break;
...
}
$event = new Event($_GET, $_POST);
$msg = $actionListener->actionPerformed($event);
echo $msg;
}
}
// 執行
new MemberController()->run();
Model 的設計
• Model 負責連線資料庫,並向資料庫取得資料
• SQL Injection 的問題通常也會在 Model 做處理
• 通常會透過 DBAL 來實作 Model
• 在這邊我們使用 ezSQL
abstract class Model {
private $conn = null;
public __construct()
{
$this->init();
}
public function init() {
if( !empty($conn) ) return;
require_once "/ezsql_path/ez_sql_core.php";
require_once "/ezsql_path/ez_sql_mysql.php";
// 連線資料庫
$this->conn = new ezSQL_mysql('db_user','db_password','db_name','db_host');
}
}
Model 的設計 (續)
class MemberModel extends Model
{
public function setCondition() {
}
public function getMemberList() {
$sql = "SELECT member_id, member_name, ... FROM members";
return $this->conn->get_results($sql);
}
public function getMemberById($member_id)
{
$sql = "SELECT member_id, member_name, ... FROM members ";
$sql .= "WHERE member_id='$member_id'";
return $this->conn->get_row($sql);
}
public function getMemberListCount() {
}
public function addMember() {
}
public function deleteMember() {
}
}
View 的設計
• View 最主要的目地是將程式的邏輯與畫面做切割
• 讓畫面的修改不會影響到程式的運作
• 通常會使用樣版引擎做為 View 的基礎
• 在這邊使用 Smarty
abstract class View {
private $tpl = null;
public __construct()
{
$this->init();
}
public function init()
{
require_once 'libs/Smarty.class.php';
$this->tpl = new Smarty();
$this->tpl->template_dir = "templates/";
$this->tpl->compile_dir = "templates_c/";
$this->tpl->left_delimiter = '<{';
$this->tpl->right_delimiter = '}>';
}
}
View 的設計 (續)
class MemberView extends View {
public showMemberListPage() {
$model = new MemberModel();
$results = $model->getMemberList();
$this->tpl->assign('members', $results);
$this->tpl->display('showMemberList.tpl');
}
public showAddMemberPage() {
}
public showDeleteMemberPage() {
}
}
Controller 的使用
• Controller 可以直接使用 View 產生畫面
• 顯示新增頁面
class ShowInsertPageAction implements ActionListener
{
private $model = null;
private $view = null;
public __construct() {
$this->model = new MemberModel();
$this->view = new MemberView();
}
public function actionPerformed($event) {
$this->view->showInsertMemberPage();
}
}
Controller 的使用 (續)
•
•
•
•
Controller 也可能執行的是一個動作,並將資料透過 Model 新增到資料庫
Controller 必須負責商業邏輯的部分包含防呆、規則、計算等動作
配合 AJAX 的前端程式設計,回應的結果可以是 JSON 而不是完整的畫面
新增會員
class DoInsertAction implements ActionListener
{
private $model = null;
private $view = null;
public __construct() {
$this->model = new MemberModel();
$this->view = new MemberView();
}
public function actionPerformed($event) {
$member_id = $event->getPost()['member_id'];
$member_name = $event->getPost()['member_name'];
if( empty($member_id) ) {
echo json_encode(false);
return;
}
$result = $this->model->addMember($member_id);
echo json_encode($result);
}
}
練習
• 採用 MVC 的架構設計會員管理
• 功能包含會員的註冊、修改、刪除、查詢
• 需使用 Dojo Toolkit 做畫面
• 需使用 AJAX 執行請求