<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                 在上一篇我們講了結構型模式,結構型模式是討論類和對象的結構的。總共有7種。而今天我們來介紹一下行為型模式。 一、什么是行為型模式? 1、設計模式:   是一套被反復使用、多數人知曉的、經過分類編目的、代碼設計的總結。就好像杯子,是被前人設計出來的,實現了儲存水的功能,解決了人們的喝水問題。大多數人喝水都用杯子。但是你不必自己再重做另外方法再做一種容器,而實現的也是同樣的功能,只要會用別人做出來的杯子喝水就能達到目的。但是杯子有很多中,實現喝水的方式也不同,比如茶水杯子,咖啡杯,啤酒杯子等等,要選擇適合自己的杯子,就如茶水要用帶過濾網的杯子,如果用不帶過濾網的會喝一嘴茶葉。合適的才是最好的。 總結出來設計模式的特性如下: 1.普遍性:經過前輩們的使用,大多人都實用的,總結提煉不斷的提升被普遍認為是實現某種事物的最有效的方法。 2.封裝性:既然是方法那我們就不用太關心細節是怎么實現的,而主要是學習怎么用這些方法模式,從而達到自己的目的。 3.面向對象性:指揮對象做事。把復雜問題簡單化。 4.最優性:要充分相信適合的就是最好的。 2、面向對象:   或許你對面向對象還有疑問?指揮對象做事,把復雜問題簡單化。那么我們就來舉個例子說明。比如我們去飯店吃飯,會叫服務員然后點菜,那我們就是指揮服務員做事,至于服務員怎么讓廚師做,廚師怎么做,這些我們都不管。我們只管是否能吃到我們叫到的菜。這個就是把復雜事情簡單化了。我們不用自己做菜,也不用知道菜怎么做,我們指揮服務員就行了,吃飯這件事就由復雜的做菜之類的變成吃這個簡單的事了。 3、行為型模式: 就是描述類和對象之間的通信和職責的。簡而言之,就是類和對象扮演什么角色,還有怎么扮演這個角色的問題。 二、行為型模式的種類   大體上分為三個大類:常見模式、已知模式、深度模式   常見模式包括: 模版方法模式命令模式 迭代器模式 觀察者模式 中介者模式 狀態式 職責鏈模式 策略模式 已知模式包括:備忘錄模式 深度模式包括:解釋器模式 訪問者模式 下面來介紹常見模式 ? 常見模式 1、模版方法模式(Template):   定義一個操作中的算法骨架,而將一些實現步驟延遲到子類當中實現。就像一個豆漿機,不管放進去的是紅豆還是黑豆,出來的都是豆漿。   好處:擴展性好,封裝不變的代碼,擴展可變的代碼   弊端:靈活性差,不能改變骨架部分。   應用場景:一類或一組具有共性的事物中 代碼實現 <?php /** * 優才網公開課示例代碼 * * 模板方法模式 Template * * @author 優才網全棧工程師教研組 * @seehttp://www.ucai.cn */ function output($string) { echo $string . "\n"; } class Request { public$token = ''; publicfunction __construct() { $this->token ='0c6b7289f5334ed2b697dd461eaf9812'; } } class Response { publicfunction render($content) { output(sprintf('response-render: %s',$content)); } publicfunction redirect($uri) { output(sprintf('response-redirect: %s', $uri)); } publicfunction json($data) { output(sprintf('response-data: %s', json_encode($data))); } } //父類,抽象類 abstract class Controller{ //封裝了輸入輸出 protected$request; protected$response; //返回數據 protected$data = 'data'; publicfunction __construct($request, $response){ $this->request = $request; $this->response = $response; } //執行請求函數,定義總體算法(template method),final防止被復寫(不允許子類改變總體算法) publicfinal function execute(){ $this->before(); if($this->valid()){ $this->handleRequest(); } $this->after(); } //定義hook methodbefore,做一些具體請求的前置處理 //非abstract方法,子類可以選擇覆蓋或不覆蓋,默認什么都不做 protectedfunction before(){ } //定義hook methodvalid,做請求的數據驗證 //非abstract方法,子類可以選擇覆蓋或不覆蓋,默認返回驗證通過 protectedfunction valid(){ returntrue; } //定義hook methodhandleRequest,處理請求 //定義為abstract方法,子類必須實現或也聲明為抽象方法(由子類的子類負責實現) abstractfunction handleRequest(); //定義hook methodafter,做一些請求的后置處理 //非abstract方法,子類可以選擇覆蓋或不覆蓋,默認直接輸出數據 protectedfunction after(){ $this->response->render($this->data); } } //子類1,實現父類開放的具體算法 class User extends Controller{ //覆蓋before方法,實現具體算法,這是一個處理用戶數據操作的控制器 //因此,我們選擇在before里面判斷用戶是否已經登錄了,這里簡單判斷下session數據 functionbefore(){ if(empty($_SESSION['auth'])){ //沒登錄就直接跳轉了,不再執行后續的操作 $this->response->redirect("user/login.php"); } } //覆蓋valid方法,這里我們驗證用戶提交數據中有沒有帶驗證token functionvalid(){ if(isset($this->request->token)){ return true; } returnfalse; } //覆蓋handleRequest方法,必選,以為父類中聲明了abstract了 functionhandleRequest(){ //做具體處理,一般根據參數執行不同的業務邏輯 } //這個類我們選擇不覆蓋after方法,使用默認處理方式 } //子類2,實現父類開放的具體算法 class Post extends Controller{ //這個類我們選擇不覆蓋before方法,使用默認處理方式 //這個類我們選擇不覆蓋valid方法,使用默認處理方式 //覆蓋handleRequest方法,必選,以為父類中聲明了abstract了 functionhandleRequest(){ //做具體處理,一般根據參數執行不同的業務邏輯 $this->data = array('title' => 'ucai'); } //覆蓋after方法,使用json格式輸出數據 functionafter(){ $this->response->json($this->data); } } class Client { publicstatic function test(){ $request = new Request(); $response = new Response(); //最終調用 $user= new User($request, $response); $user->execute(); //最終調用 $post= new Post($request, $response); $post->execute(); } } Client::test(); 2、命令模式(Command) :   行為請求者與行為實現者解耦。就像軍隊里的“敬禮”,不管是誰聽到這個命令都會做出標準的敬禮動作。   好處:便于添加和修改行為,便于聚合多個命令   弊端:造成過多具體的命令類   應用場景:對要操作的對象,進行的相同操作 代碼實現 <?php /** * 優才網公開課示例代碼 * * 命令模式 Command * * @author 優才網全棧工程師教研組 * @seehttp://www.ucai.cn */ function output($string) { echo $string . "\n"; } class Document { private$name = ''; public function __construct($name) { $this->name = $name; } publicfunction showText() { output(sprintf("showText: %s", $this->name)); } publicfunction undo() { output(sprintf("undo-showText: %s", $this->name)); } } class Graphics { private$name = ''; publicfunction __construct($name) { $this->name = $name; } publicfunction drawCircle() { output(sprintf("drawCircle: %s", $this->name)); } publicfunction undo() { output(sprintf("undo-drawCircle: %s", $this->name)); } } class Client { publicstatic function test() { $document = newDocument('A'); $graphics = newGraphics('B'); $document->showText(); $graphics->drawCircle(); $document->undo(); } } Client::test(); <?php /** * 優才網公開課示例代碼 * * 命令模式 Command * * @author 優才網全棧工程師教研組 * @seehttp://www.ucai.cn */ function output($string) { echo $string . "\n"; } interface Command { publicfunction execute(); publicfunction undo(); } class Document implements Command { private$name = ''; publicfunction __construct($name) { $this->name = $name; } publicfunction execute() { output(sprintf("showText: %s", $this->name)); } publicfunction undo() { output(sprintf("undo-showText: %s", $this->name)); } } class Graphics implements Command { private$name = ''; publicfunction __construct($name) { $this->name = $name; } publicfunction execute() { output(sprintf("drawCircle: %s", $this->name)); } publicfunction undo() { output(sprintf("undo-drawCircle: %s", $this->name)); } } class Client { publicstatic function test() { $array = array(); array_push($array, new Document('A')); array_push($array, new Document('B')); array_push($array, new Graphics('C')); array_push($array, new Graphics('D')); foreach ($array as $command) { $command->execute(); } $top = array_pop($array); $top->undo(); } } Client::test(); <?php /** * 優才網公開課示例代碼 * * 命令模式 Command * * @author 優才網全棧工程師教研組 * @seehttp://www.ucai.cn */ function output($string) { echo $string . "\n"; } interface Command { publicfunction execute(); publicfunction undo(); } class Document { private$name = ''; publicfunction __construct($name) { $this->name = $name; } publicfunction showText() { output(sprintf("showText: %s", $this->name)); } publicfunction undo() { output(sprintf("undo-showText: %s", $this->name)); } } class Graphics { private$name = ''; publicfunction __construct($name) { $this->name = $name; } publicfunction drawCircle() { output(sprintf("drawCircle: %s", $this->name)); } publicfunction undo() { output(sprintf("undo-drawCircle: %s", $this->name)); } } class DocumentCommand implements Command { private$obj = ''; publicfunction __construct(Document $document) { $this->obj = $document; } publicfunction execute() { $this->obj->showText(); } publicfunction undo() { $this->obj->undo(); } } class GraphicsCommand implements Command { private$obj = ''; publicfunction __construct(Graphics $graphics) { $this->obj = $graphics; } publicfunction execute() { $this->obj->drawCircle(); } publicfunction undo() { $this->obj->undo(); } } class Client { publicstatic function test() { $array = array(); array_push($array, new DocumentCommand(new Document('A'))); array_push($array, new DocumentCommand(new Document('B'))); array_push($array, new GraphicsCommand(newGraphics('C'))); array_push($array, new GraphicsCommand(new Graphics('D'))); foreach ($array as $command) { $command->execute(); } $top = array_pop($array); $top->undo(); } } Client::test(); 3、迭代器模式(Iterator):   訪問聚合對象內容而不暴露內部結構。就像一個雙色球彩票開獎一樣,每次都是搖出七個球,不能能搖不是七個球的中獎號碼組合。   好處:以不同方式遍歷一個集合   弊端:每次遍歷都是整個集合,不能單獨取出元素   應用場景:需要操作集合里的全部元素。 代碼實現: <?php /** * 優才網公開課示例代碼 * * 迭代器模式 Iterator * * @author 優才網全棧工程師教研組 * @seehttp://www.ucai.cn */ function output($string) { echo $string . "\n"; } class RecordIterator implements Iterator{ private$position = 0; //注意:被迭代對象屬性是私有的 private$records = array(); publicfunction __construct(Array $records) { $this->position = 0; $this->records = $records; } functionrewind() { $this->position = 0; } functioncurrent() { return$this->records[$this->position]; } functionkey() { return$this->position; } functionnext() { ++$this->position; } functionvalid() { returnisset($this->records[$this->position]); } } class PostListPager { protected$record = array(); protected$total = 0; protected$page = 0; protected$size = 0; publicfunction __construct($category, $page, $size) { $this->page = $page; $this->size = $size; //query db $total = 28; $this->total = $total; $record = array( 0 => array('id'=> '1'), 1 => array('id'=> '2'), 2 => array('id'=> '3'), 3 => array('id'=> '4'), ); // $this->record = $record; } publicfunction getIterator() { return newRecordIterator($this->record); } publicfunction getMaxPage() { $max = intval($this->total /$this->size); return $max; } publicfunction getPrevPage() { return max($this->page - 1,1); } publicfunction getNextPage() { return min($this->page + 1,$this->getMaxPage()); } } class Client { publicstatic function test(){ $pager = new PostListPager(1,2, 4); foreach ($pager->getIterator() as $key => $val) { output(sprintf('Key[%d],Val[%s]', $key, json_encode($val))); } output(sprintf('MaxPage[%d]', $pager->getMaxPage())); output(sprintf('Prev[%d]', $pager->getPrevPage())); output(sprintf('Next[%d]', $pager->getNextPage())); $iterator =$pager->getIterator(); while($iterator->valid()){ print_r($iterator->current()); $iterator->next(); } $iterator->rewind(); } } Client::test(); 4、觀察者模式(Observer):   又叫發布訂閱模式,當一個主體對象發生改變時,依賴它的多個觀察者對象都得到通知并自動更新響應。就像報社一樣,今天發布的消息只要是看這份報紙的人看到的都是同樣的內容。如果發布另一份報紙,也是一樣的。   好處:廣播式通信,范圍大,一呼百應,便于操作一個組團,“公有制”   弊端:不能單獨操作組團里的個體,不能實行按需分配   應用場景:操作多個對象,并操作相同。 代碼實現: <?php /** * 優才網公開課示例代碼 * * 觀察者模式 Observer * * @author 優才網全棧工程師教研組 * @seehttp://www.ucai.cn */ function output($string) { echo $string . "\n"; } //訂單數據對象簡單模擬,這個是實際需要被觀察的對象(Subject),但是我們將其獨立,然后 //通過構造方法傳入到我們模式中的Subject中,這樣使具體業務更加獨立 class Order{ //訂單號 private$id = ''; //用戶ID private$userId = ''; //用戶名 private$userName = ''; //價格 private$price = ''; //下單時間 private$orderTime = ''; //訂單數據填充簡單模擬,實際應用中可能會讀取用戶表單輸入并處理 publicfunction __set($name, $value){ if(isset($this->$name)){ $this->$name = $value; } } //獲取訂單屬性 public function__get($name){ if(isset($this->$name)){ return $this->$name; } return""; } } //假設的DB類,便于測試,實際會存入真實數據庫 class FakeDB{ publicfunction save($data){ returntrue; } } class Client { publicstatic function test() { //初始化一個訂單數據 $order= new Order(); $order->id = 1001; $order->userId = 9527; $order->userName = "God"; $order->price = 20.0; $order->orderTime = time(); //向數據庫保存訂單 $db =new FakeDB(); $result = $db->save($order); if($result){ //實際應用可能會寫到日志文件中,這里直接輸出 output( "[OrderId:{$order->id}] [UseId:{$order->userId}][Price:{$order->price}]" ); //實際應用會調用郵件發送服務如sendmail,這里直接輸出 output( "Dear {$order->userName}: Your order {$order->id} wasconfirmed!" ); //實際應用會調用郵件發送服務如sendmail,這里直接輸出 output( "Dear Manager: User{$order->userName}(ID:{$order->userId}) submitted a new order {$order->id},please handle it ASAP!" ); } } } Client::test(); <?php /** * 優才網公開課示例代碼 * * 觀察者模式 Observer * * @author 優才網全棧工程師教研組 * @seehttp://www.ucai.cn */ function output($string) { echo $string . "\n"; } //訂單數據對象簡單模擬,這個是實際需要被觀察的對象(Subject),但是我們將其獨立,然后 //通過構造方法傳入到我們模式中的Subject中,這樣使具體業務更加獨立 class Order{ //訂單號 private$id = ''; //用戶ID private$userId = ''; //用戶名 private$userName = ''; //價格 private$price = ''; //下單時間 private$orderTime = ''; //訂單數據填充簡單模擬,實際應用中可能會讀取用戶表單輸入并處理 publicfunction __set($name, $value){ if(isset($this->$name)){ $this->$name = $value; } } //獲取訂單屬性 publicfunction __get($name){ if(isset($this->$name)){ return $this->$name; } return""; } } //被觀察者, 負責維護觀察者并在變化發生是通知觀察者 class OrderSubject implements SplSubject { private$observers; private$order; publicfunction __construct(Order $order) { $this->observers = new SplObjectStorage(); $this->order = $order; } //增加一個觀察者 publicfunction attach(SplObserver $observer) { $this->observers->attach($observer); } //移除一個觀察者 publicfunction detach(SplObserver $observer) { $this->observers->detach($observer); } //通知所有觀察者 publicfunction notify() { foreach ($this->observers as $observer) { $observer->update($this); } } //返回主體對象的具體實現,供觀察者調用 publicfunction getOrder() { return$this->order; } } //記錄業務數據日志 (ActionLogObserver),實際可能還要抽象一層以處理不同的Action(業務操作),這里省略 class ActionLogObserver implements SplObserver{ publicfunction update(SplSubject $subject) { $order = $subject->getOrder(); //實際應用可能會寫到日志文件中,這里直接輸出 output( "[OrderId:{$order->id}] [UseId:{$order->userId}][Price:{$order->price}]" ); } } //給用戶發送訂單確認郵件 (UserMailObserver) class UserMailObserver implements SplObserver{ publicfunction update(SplSubject $subject) { $order = $subject->getOrder(); //實際應用會調用郵件發送服務如sendmail,這里直接輸出 output( "Dear {$order->userName}: Your order {$order->id} wasconfirmed!" ); } } //給管理人員發訂單處理通知郵件 (AdminMailObserver) class AdminMailObserver implements SplObserver{ publicfunction update(SplSubject $subject) { $order = $subject->getOrder(); //實際應用會調用郵件發送服務如sendmail,這里直接輸出 output( "Dear Manager: User{$order->userName}(ID:{$order->userId}) submitted a new order{$order->id}, please handle it ASAP!" ); } } //假設的DB類,便于測試,實際會存入真實數據庫 class FakeDB{ publicfunction save($data){ returntrue; } } class Client { publicstatic function test() { //初始化一個訂單數據 $order= new Order(); $order->id = 1001; $order->userId = 9527; $order->userName = "God"; $order->price = 20.0; $order->orderTime = time(); //綁定觀察者 $subject = new OrderSubject($order); $actionLogObserver = new ActionLogObserver(); $userMailObserver = newUserMailObserver(); $adminMailObserver = new AdminMailObserver(); $subject->attach($actionLogObserver); $subject->attach($userMailObserver); $subject->attach($adminMailObserver); //向數據庫保存訂單 $db =new FakeDB(); $result = $db->save($order); if($result){ //通知觀察者 $subject->notify(); } } } Client::test(); 5、中介者模式(Mediator):   用中介對象封裝一系列的對象交互,中介使各對象不需要顯式地相互引用。類似于郵局,郵寄者和收件者不用自己跑很遠路,通過郵局就可以。   好處:簡化了對象之間的關系,減少子類的生成   弊端:中介對象可能變得非常復雜,系統難以維護   應用場景:不需要顯示地建立交互 代碼實現: <?php /** * 優才網公開課示例代碼 * * 中介者模式 Mediator * * @author 優才網全棧工程師教研組 * @seehttp://www.ucai.cn */ function output($string) { echo $string . "\n"; } abstract class Mediator { // 中介者角色 abstractpublic function send($message,$colleague); } abstract class Colleague { // 抽象對象 private$_mediator = null; publicfunction __construct($mediator) { $this->_mediator = $mediator; } publicfunction send($message) { $this->_mediator->send($message,$this); } abstractpublic function notify($message); } class ConcreteMediator extends Mediator { // 具體中介者角色 private$_colleague1 = null; private$_colleague2 = null; publicfunction send($message,$colleague) { if($colleague == $this->_colleague1) { $this->_colleague1->notify($message); } else{ $this->_colleague2->notify($message); } } publicfunction set($colleague1,$colleague2) { $this->_colleague1 = $colleague1; $this->_colleague2 = $colleague2; } } class Colleague1 extends Colleague { // 具體對象角色 publicfunction notify($message) { output(sprintf('Colleague-1: %s', $message)); } } class Colleague2 extends Colleague { // 具體對象角色 publicfunction notify($message) { output(sprintf('Colleague-2: %s', $message)); } } class Client { publicstatic function test(){ //client $objMediator = new ConcreteMediator(); $objC1= new Colleague1($objMediator); $objC2= new Colleague2($objMediator); $objMediator->set($objC1,$objC2); $objC1->send("to c2 from c1"); $objC2->send("to c1 from c2"); } } Client::test(); 說明:剩下的幾種模式將在下次發布,敬請關注。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看