摘要:在所有設(shè)計模式中,訪問者模式算得上比較難理解的一種設(shè)計模式。雖然這種模式比較難理解,但是也需要去知道這種模式具體是怎么回事兒,我將從最簡單的代碼講起,嘗試去說說這種模式的由來。比較以上兩段代碼的區(qū)別,體會思維方式,這就是訪問者模式的雛形。
在所有設(shè)計模式中,訪問者模式算得上比較難理解的一種設(shè)計模式。雖然這種模式比較難理解,但是也需要去知道這種模式具體是怎么回事兒,我將從最簡單的代碼講起,嘗試去說說這種模式的由來。
先給定一個場景:顧客去商店買物品,購物結(jié)束后需要在收銀員進(jìn)行結(jié)賬。
這里具體羅列一下幾個關(guān)鍵詞:顧客(client)、物品(goods)和收銀員(cashier)
于是就有以下代碼:
class Cashier { public function checkGoods(Goods $goods) { echo "【Goods】Title: {$goods->title}, price: {$goods->price}"; } } class Goods { public $title = ""; public $price = 0; public function __construct($title, $price) { $this->title = $title; $this->price = $price; } } /* client */ $pencil = new Goods("鉛筆", 2.5); $cashier = new Cashier(); $cashier->checkGoods($pencil);
總體解釋:
顧客購買一支鉛筆
顧客將鉛筆交給收銀員結(jié)賬(checkGoods)
以上沒問題,很多類似的項目也是這樣設(shè)計的。宏觀來說 cashier 作為服務(wù)去結(jié)賬是沒有問題的,畢竟收銀員就是給客戶結(jié)賬的,其實這里有點類似外觀模式(Facade Pattern)。
那么有沒有辦法換一種思路去設(shè)計呢?看下面的代碼:
class Cashier { public function checkGoods(Goods $goods) { echo "【Goods】Title: {$goods->title}, price: {$goods->price}"; } } class Goods { public $title = ""; public $price = 0; public function __construct($title, $price) { $this->title = $title; $this->price = $price; } public function checkSelf(Cashier $cashier) { $cashier->checkGoods($this); } } $pencil = new Goods("鉛筆", 2.5); $cashier = new Cashier(); $pencil->checkSelf($cashier);
以上代碼在 Goods 中加了一個 checkSelf 方法用于接收 Cashier 實例,在 checkSelf 的這個方法中,我們調(diào)用了實例的 checkGoods 方法。改寫 client 端的代碼,將不在使用 checkGoods 方法進(jìn)行檢查,而使用的是 checkSelf 方法將 cashier 傳入 Goods 中。
比較以上兩段代碼的區(qū)別,體會思維方式,這就是訪問者模式的雛形。
接下來就是抽象了。把實例抽象化,該用接口的用接口,該用繼承的用繼承。
以下就是改寫上面的例子
interface IVisitor { public function visit(IElement $element); } interface IElement { public function accept(IVisitor $visitor); } class Cashier implements IVisitor { public function visit(IElement $element) { echo "【Goods】Title: {$element->title}, price: {$element->price}"; } } class Goods implements IElement { public $title = ""; public $price = 0; public function __construct($title, $price) { $this->title = $title; $this->price = $price; } public function accept(IVisitor $visitor) { $visitor->visit($this); } } $pencil = new Goods("鉛筆", 2.5); $cashier = new Cashier(); $pencil->accept($cashier);
這樣看起來是不是能夠理解不少呢?
其實設(shè)計模式?jīng)]那么復(fù)雜,大部分是一種思維方式的轉(zhuǎn)變。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/31406.html
摘要:概述到這里我們講說面向?qū)ο蟮南盗胁糠值淖詈笠粋€課程,面向?qū)ο蟊仨氄莆諆蓚€東西一個是對象的創(chuàng)建一個是繼承。只需要記住一句話,屬性放在構(gòu)造函數(shù)里面,方法放在原型上。 概述 到這里我們講說js面向?qū)ο蟮南盗胁糠值淖詈笠粋€課程,面向?qū)ο蟊仨氄莆諆蓚€東西一個是對象的創(chuàng)建一個是繼承。這節(jié)課我們重點說說這兩個問題最后我們說下在ES6里面面向?qū)ο笤趺赐妗?1對象的創(chuàng)建 我們第一節(jié)課已經(jīng)就會用了,單體模...
摘要:本文會以引出問題為主,后面有時間的話,筆者陸續(xù)會抽些重要的知識點進(jìn)行詳細(xì)的剖析與解答。敬請關(guān)注服務(wù)端思維微信公眾號,獲取最新文章。 原文地址:梁桂釗的博客博客地址:http://blog.720ui.com 這里,筆者結(jié)合自己過往的面試經(jīng)驗,整理了一些核心的知識清單,幫助讀者更好地回顧與復(fù)習(xí) Java 服務(wù)端核心技術(shù)。本文會以引出問題為主,后面有時間的話,筆者陸續(xù)會抽些重要的知識點進(jìn)...
摘要:周五就想寫這篇文章,但是無奈花花世界的誘惑太多就一直拖到了今天,自責(zé)遍進(jìn)入正題對象用于表示一個異步操作的最終狀態(tài)完成或失敗,以及其返回的值。 周五就想寫這篇文章,但是無奈花花世界的誘惑太多……就一直拖到了今天,自責(zé)1e4遍;進(jìn)入正題Promise: Promise 對象用于表示一個異步操作的最終狀態(tài)(完成或失敗),以及其返回的值。 上為MDNPromise的定義;ES6規(guī)定Promis...
閱讀 964·2023-04-26 02:56
閱讀 9438·2021-11-23 09:51
閱讀 1850·2021-09-26 10:14
閱讀 2980·2019-08-29 13:09
閱讀 2154·2019-08-26 13:29
閱讀 571·2019-08-26 12:02
閱讀 3562·2019-08-26 10:42
閱讀 3000·2019-08-23 18:18