设计模式故事会
想著用講故事的方式對各個設計模式進行一個稍微形象一些的描述. 當然, 某些因為沒有想到特別好的例子, 可能比喻的并不是那么的恰當, 望賜教. 絞盡腦汁啊, 盡力貼近設計模式其本來的意圖. 主要為了加強一些自己對設計模式的理解. 進入正題:
小王是一名心懷夢想的90后青年, 他獨自創辦了太原現代科技公司, 并召集了一幫志同道合的小伙伴, 夢想改變世界.
單例模式
太原現代科技公司接到了一個項目, 這時就需要大家發揮各種聰明才智了. 于是, 每個人都將自己的想法記錄下來, 然后等到每天開會的時候把每個人的新想法收集起來, 統一進行討論.
沒幾天, 小王就發現了這種方式的低效, 如果能夠將每個人的想法實時的收集起來就好了. 這樣每個人都能夠實時看到其他人的新想法, 在思考的同時還能夠激發自己的靈感. 問題是如何實現呢? 有一個東西叫做多人在線協作文檔, 就用它了. 創建一個文檔, 每個人的新想法都寫到這個文檔中, 每個人看到和操作的都是同一個文檔.
小王的團隊利用這個公共文檔, 很快碰撞出了新奇的想法, 項目大獲成功.
單例模式: 確保某一個類只有一個實例,而且自行實例化并向整個系統提供這個實例.
工廠方法模式
公司最近開始了新的市場嘗試, 開網店. 賣什么呢? 從小孩子入手, 剛開始嘛, 先簡單涉獵一下. 就賣鉛筆盒. 但是自己畢竟并不會生產, 畢竟整個廠子投入有些大, 也沒有必要. 聯系了文具廠 A、B、C, 只賣三個品牌的鉛筆盒. 每次進貨的時候, 只需要分別告訴他們自己需要鉛筆盒, 而不需要告訴具體的品牌, 因為他們知道自己生產的品牌. 如此一來, 對于公司來說, 三個生產廠家其實是一樣的, 只需要告訴他們: “我要鉛筆盒” 即可.
工廠方法模式: 定義一個用于創建對象的接口,讓子類決定實例化哪一個類. 工廠方法使一個類的實例化延遲到其子類
抽象工廠模式
之前的鉛筆盒買的很好, 小王決定擴大規模. 不光賣鉛筆盒, 還要賣碳素筆, 橡皮等. 廠家還是原來的三家, 畢竟已經合作這么久了. 同樣的, 進貨的時候也不需要指定品牌, 只要告訴他們: “我要鉛筆盒”, “我要碳素筆”, 即可. 操作起來一樣很方便.
(對了, 抽象工廠還有個更形象的例子, 那就是跨平臺. 比如一個軟件要在 Windows, Linux, MaxOS 下運行, 可以通過抽象工廠來消除操作系統之間的差異, 對使用者來說, 調用接口完全一致)
抽象工廠模式: 為創建一組相關或互相依賴的對象提供一個接口,而且無須制定它們的具體類
建造者模式
這天, 小王下班回到家, 看到媳婦在做飯. 因為之前每次都是一回家就吃到熱騰騰的飯菜, 所以她自然也就沒有關心過飯菜是如何做成的. 今天閑來無事, 進廚房幫幫忙, 就拿簡簡單單的煮米飯為例, 要經過淘米、加水、開火等步驟, 而一些菜的制作步驟則更是繁瑣. 自己之前只知道吃米飯, 米飯做好了, 吃菜, 菜做好了. 想到這, 小王更覺得自己應該多關心關心媳婦了, 不過沒多大一會, 他就因為笨手笨腳被趕出了廚房.
建造者模式: 將一個復雜對象的構建與它的表示分離, 使得同樣的構建過程可以創建不同的表示
模板方法模式
公司因為擴張, 現在需要再招進一些人才來, 既然招人, 那少不了各種流程, 不然整個都亂了嘛. 一個新員工的入職流程如下: 收簡歷 -> 簡歷篩選 -> 部門面試 -> 人事面試 -> 小王面試 -> 辦理入職. 即使流程明確了, 在 簡歷篩選, 部門面試這兩個步驟, 各個部門之間是有差異的, 要由各個部門來進行具體操刀, 當然, 大的流程是不變的. 所以現在的流程很明確了, 整體流程各個部門完全一致, 各部門只需要處理其中的 簡歷篩選 和 部門面試兩個環節就可以了.
模板方法模式: 定義一個操作中的算法的框架,而將一些步驟延遲到子類中. 使得子類可以不改變一個算法的結構即可重定義該算法的某些特定步驟
原型模式
在公司內部, 難免要進行資源之間的共享. 當然現在智能化辦公, 更多的是電腦之間的資源共享. 如何實現資源的共享呢? 還好現代操作系統都提供的復制粘貼的功能. 文件 A 可以通過復制粘貼的操作, 產生很多個完全相同的文件, 這些文件可能下發到不同人的手中來進行不同的業務處理. (對于原型模式來說, 這個復制的操作是由文件自己來完成的)
原型模式: 用原型實例指定創建對象的種類, 并且通過拷貝這些原型創建新的對象.
代理模式
最近公司發現有些某媒體濫用本公司的知識產權而沒有得到授權, 所以決定通過法律的手段進行維權. 既然要走法律的流程, 那專業的事情自然要交給專業的人來辦, 律師. 請律師有什么好處呢? 想象一下如果沒有律師, 你需要事前準備、事后追進、出庭上訴等等一系列的事情, 而請了專業人士就不一樣了, 你只需要在開庭的時候出庭, 而其他的一些事前及善后都有人來處理了, 你完全不用關心.
代理模式: 為其他對象提供一種代理以控制對這個對象的訪問
中介者模式
小麗是公司的一名員工, 最近老板交給她一個任務, 公司所在的辦公地址快要到期了, 要小麗找一個新的辦公樓. 于是小麗就出去挨家挨戶打聽哪里有房出租, 然后再依次找房主進行談判. 就這么過了兩天, 可把小麗給折騰夠嗆, 房子也還沒有著落.
小麗心想, 這也不是個辦法啊. 她走在回家的路上, 看到道路旁邊有一家 XX 房屋中介, 進去一問, 嘿, 合適. 將需要的信息記錄在案, 第二天, 接到了中介打來的電話, 房子找到了. 經過這次, 小麗明白了一個道理, 專業的事情還是要交給專業的人來吧. 自己只要告訴中介需要什么房子, 連房主都不需要見到, 房子就租下來了, 比起自己出去找, 效率不知道高了多少倍.
中介者模式: 將多個對象間的交互委托給中介者進行, 從而降低類之間的耦合
責任鏈模式
當公司要下達命令時, 小王并不會依次的去通知公司的每一個人. 而是只將命令傳達給秘書, 秘書再傳達給各經理, 這樣一層一層的將命令下發出去, 若員工小張接到命令, 發現是交給自己的任務, 那他就可以進行處理了. 而小王通過這樣處理, 只需要將命令交給秘書, 就可以確保最終一定可以到達需要處理的人手中. 每個人在自己無法處理的時候, 都會將命令傳遞給下一個人, 最終傳到處理的人手中. 對于小王來說, 那操作簡單了, 不管什么命令, 統一交給秘書就好了. 而對于每一個人來說, 亦是如此, 只要交給下一個人就行了.
責任鏈模式: 使多個對象都有機會處理請求, 從而避免了請求的發送者和接受者之間的耦合關系. 將這些對象連成一條鏈, 并沿著這條鏈傳遞該請求,直到有對象處理它為止
命令模式
在公司中, 下達一個任務并不會將任務的每個執行步驟都一一說明. 比如, 如果需要打印一份文件, 只需要說: “幫我把這份文件打印一下”, 而不會說: “先把這份文件打開, 連接打印機, 點開菜單, 選擇打印, 選擇格式, 選擇打印機…”. 如果是這樣, 分配任務的人也太累了吧. 所以往往只要把一個對方明白的命令布置下去, 對方自然會自行完成各個步驟來最終完成這個命令.
命令模式: 將一個請求封裝成一個對象, 從而讓你使用不同的請求將客戶端參數化, 對請求排隊或者記錄請求日志, 可以提供命令的撤銷和恢復功能
裝飾模式
公司要舉辦年會, 其中有個舞蹈表演, 自然要購置上配套的服裝來, 相比穿休閑裝跳舞, 配上對應的服裝, 舞美立刻就提升了不止一個檔次, 效果也要好得多. 演員還是那個演員, 舞蹈動作也沒有發生變化, 而因為換上了一套服裝, 立刻增強了演出的觀感體驗.
裝飾模式: 動態的給一個對象添加一些額外的職責
策略模式
公司最近打算投資一些剛剛起步的小公司, 于是成立了北京投資分公司. 既然要投資, 那定然不能隨隨便便, 所以針對不同的場景擬定了一系列的投資策略. 當需要針對教育類的公司進行投資時, 就將擬訂好的教育類投資策略執行, 以此來最大可能的增加盈利的概率, 進入21世紀了嘛, 讓數據來說話.
策略模式: 定義一組算法, 將每個算法都封裝起來, 并且使它們之間可以互換
門面模式
公司在處理用戶需求的時候, 如果產品的問題找產品、技術的問題找技術. 估計客戶都要抓狂了, 人家又不知道這個需求應該找誰. 所以指定了小孫和客戶進行對接, 不管用戶有什么類型的需求變更, 統一都告訴小孫, 然后小孫來再來將需求分配到各個具體的部門手上. 如此一來, 客戶的滿意度大大提高.
門面模式: 要求一個子系統的外部與其內部的通信必須通過一個統一的對象進行. 門面模式提供一個高層次的接口, 使得子系統更易于使用.
迭代器模式
公司最近來面試的人越來越多, 而面試官又只有那么幾位, 難免會讓部分面試人員稍微等待一下. 如何規范的管理這個過程呢? 要讓早到的人更早的面試. 排隊, 沒錯簡單粗暴的排隊. 每次面試完一位之后, 只要說: “下一位”, 就可以按照順序進行下一場面試了. 當然, 你也可以問問還有沒有面試人員, 如果沒有就不用叫下一位進來咯.
迭代器模式: 它提供一種方法訪問一個容器對象中各個元素, 而又不需暴露該對象的內部細節
適配器模式
公司的軟件有用戶使用了, 難免會收到用戶各種問題的反饋, 但是用戶每個人填寫反饋信息的格式都比較隨意, 比如問題描述、問題類型、發生頻率等等, 用戶整體都放到描述中了, 如此一來, 查看反饋信息自然就成為了一個十分困難的事情. 作為一個互聯網公司, 自然想到了通過軟件來解決問題. 于是開發了這樣一款程序, 可以將反饋的各個數據從用戶的描述中提取出來, 然后分門別類的展現在面前. 嗯, 這樣一來處理反饋的問題就比之前舒服多了, 而且效率也快得多了.
適配器模式: 將一個類的接口變換成客戶端所期待的另一種接口, 從而使原本因接口不匹配而無法在一起工作的兩個類能夠在一起工作
組合模式
隨著公司的規模變大, 有必要進行公司的層次化, 也方便管理些. 例如董事會管理下邊的各個子公司、各子公司下邊又開設多個不同部門、各個部門下又有多個小組… 如此一來, 整個公司架構就成了一個樹形的結構, 就像一個家族的族譜一樣. 架構清晰了, 管理起來也就較之前方便的多了.
組合模式: 將對象組合成樹形結構以表示 “部分-整體” 的層次結構,使得用戶對單個對象和組合對象的使用具有一致性.
觀察者模式
小王的公司接到一個項目, 在一個大商場里, 難免會有些偷偷摸摸的人拿了東西不付款, 所以該商場在每個出入口各安排了一名警務人員, 負責對所有出商場的人進行例行檢查. 但這無疑會極大的耗費成本. 所以想請小王來幫著通過科技的手段解決一下面臨的問題.
小王在公司召開會議, 研討此事的解決方案, 大家都各抒己見. 最終敲定了一個方案, 在每個出口, 不設專門的人員檢查, 只安裝一部機器, 該機器會自動對每個出入的人員進行檢查, 當檢查到沒有付款的客人時, 會通知警務人員過來處理. 自從安裝了這個設備, 商場多個出口, 只需要配置一個警務人員就可以處理了, 而這個警務人員也不用到每個出口盯梢, 只要坐著等報警裝置發出通知, 當接收到通知后, 自己再過去處理就行了.
觀察者模式: 當滿足某個條件時, 會順序調用預先定義好的方法
訪問者模式
公司每月要給每個員工發工資, 而對于不同的員工, 工資的計算標準是不一樣的. 有的人每天工資100, 有的人每天這是500, 而有的人是計算時薪, 有的人計算日薪, 有的人計算年薪. 針對這種情況, 就要進行差異處理, 針對不同的薪資制度, 指定不同的計算規則, 在計算薪資時, 雖然各個員工的計算基數是一樣的(時間), 但是因為規則不同, 計算出的薪資也自然不同.
訪問者模式: 封裝一些作用于某種數據結構中的各元素的操作, 它可以在不改變數據結構的前提下定義作用于這些元素的新的操作
備忘錄模式
小胡是公司的后端技術開發人員, 有時難免會在工作 A 中臨時被叫走解決一些其他的問題, 當問題解決完回來后, 經常無法快速進入之前的工作狀態, 忘記了之前的工作進度, 甚至忘記了之前在做什么工作, 這讓他很是苦惱. 不過最近經過高人指點, 發現了備忘錄這個神奇的東西, 每次在工作中斷的時候, 通過備忘錄將當前的工作進度等記錄下來, 當回來是翻看備忘錄可以快速恢復到之前的工作狀態.
備忘錄模式: 在不破壞封裝性的前提下, 捕獲一個對象的內部狀態, 并在該對象之外保存這個狀態. 這樣以后就可將該對象回復到原先保存的狀態
解釋器模式
小王還沒有到家, 就收到了妻子發來的消息: “快到家了么?”. 這句話想必是個中國人就能看懂. 但是小王畢竟不是一般人, 他由此想到了: “快” 是一個時間上的量詞, “到家了” 是一個空間上的狀態, “么” 是一個疑問預期詞, "?"標識句子結束. 而這一連串的處理, 都是大腦在無意識之中幫我們做了.
解釋器模式: 給定一門語言,定義它的文法的一種表示, 并定義一個解釋器, 該解釋器使用該表示來解釋語言中的句子
狀態模式
小李是現代科技公司北京投資分公司的董事長, 總公司每月會定期的對分公司的投資報表, 賬上流水進行核實查驗. 而投資公司的投資方向也是由總公司調查后定下的. 即, 總公司將投資方向告知后, 其他一概不管, 即可每月正常查驗. 而內部的資產切換等等, 都是由子公司來實現的, 總公司一概不去關心.
狀態模式: 由調用者將狀態設置好, 對象可根據不同的狀態有不同的表現
橋梁模式
公司最近因為人員增加, 需要購置一批新的計算機用于辦公, 購買了幾種不同品牌的計算機, 包括惠普、聯想、戴爾、華碩等等, 對于員工來說, 其實并不關心使用的是什么品牌的計算機, 對于各種品牌的計算機, 即使其內部構件不同, 但是使用上來說沒有什么區別.
橋梁模式 :將抽象和實現解耦, 使得兩者可以獨立的變化
享元模式
在公司中為了減少不必要的浪費, 有一些資源是大家共享的, 比如飲水機、打印機等等, 這些資源是誰用到的時候就去用, 沒人用的時候就放在那里等待被使用. 以此達到資源的利用最大化.
享元模式: 使用共享對象可有效的支持大量的細粒度的對象
終于寫完了, 這文章寫到中間一度差點放棄了. 這兩天決定逼一定要自己寫完. 主要這玩意網上找半天也沒有人將設計模式比做故事, 純靠想象, 有了當初小學被老師逼著一天一篇想象文的感覺. 寫完了舒服多了, 這文章有個草稿, 被拖了一個多月了, 估計不逼自己一把, 這文章就擱置了.
最后, 祝愿小王的公司越來越好…
總結
- 上一篇: 仿58 php框架源码,转转最新源码
- 下一篇: redis的多路复用是什么鬼