PHP 板


LINE

看板 PHP  RSS
你要設計一個方法,要能通過floppy bird的關卡 一種鳥只能飛低、超低、高、超高 假設你寫了一個這樣只能飛高的鳥的class class FlyHighBird { public function fly() { return "fly high"; } } 但是floppy bird的關卡的class中 Class Stage { private $bird; private $interspace; function __construct() { $this->bird = new FlyHighBird(); } function check() { if($this->bird->fly() == $interspace) return true; return false; } // other method dynamically change $interspace } Stage在編譯時期就決定依賴於Bird物件 那麼你這隻只能飛高的鳥,勢必過不了關卡現在空隙位置是 低、超低、或超高的檢查 那麼要能一直通過不同高度的關卡檢查, 你勢必要在runtime改變Stage依賴的物件才行 其實Stage根本不care你是哪種鳥,甚至根本不care你是不是鳥, 他只在乎你是飛的高還是飛的低,也就是只在乎你的 "飛的行為",你手邊有四種鳥都只能飛不同的高度,那麼你只要能動態改變Stage依賴 的$bird物件中的實作,似乎就能通過每一次的檢查 所以你把"飛的行為"從四種鳥的class中一般化成介面 interface FlyBehavior { public function fly(); } 四種鳥分別實作這個介面完成四種不同高度的飛行行為 改變Stage相依的物件 class Stage { private $flyBehavior; private $interspace; function setFlyBehavior($flyBehavior) { $this->flyBehavior = $flyBehavior; } function check() { if($this->flyBehavior->fly() == $interspace) return true; return false; } //other methods } 現在Stage 沒有在編譯時期依賴於某一種鳥類了,而是透過FlyBehavior介面 從Stage的外部注入其中一種鳥類的實作,來動態透過setFlyBehavior的替換目前 依賴的實作,這種依賴關係從原本自己物件內部,到被抽到外部決定再透過setter 或建構子注入就是依賴注入,能做到runtime才根據一些參數 (比如說Stage有個方法getInterspace()提供給你$interspace的數值,再在外部加以判斷) 決定要注入哪一種實作,來達到通過每一次檢查的彈性 將來floppy bird改版了,要檢查是否到達"宇宙的高度",才算通過 你只要打造一個火箭的Class,一樣完成FlyBehavior的實作,讓他飛到宇宙的高度 再注入到Stage物件就能通過關卡了,而你"並沒有修改Stage一開始相依物件的程式碼" 因為Stage原本直接依賴於某種鳥類的實作,這樣的關係被"介面"decoupling了 也就是"針對介面寫程式,不要針對實作寫程式"的OO守則 配合DI的方式能做到更多面對需求變更時,還能保有彈性,你要修改的程式少了很多 --



※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 125.224.178.103
※ 文章網址: https://webptt.com/m.aspx?n=bbs/PHP/M.1433858945.A.BDA.html ※ 編輯: banjmin (125.224.178.103), 06/09/2015 22:12:44
1F:推 tkdmaf: 甚至不care你是不是鳥XDD... 06/10 00:56
2F:推 Den3: 想請問這是為了解決不要重新編譯的問題,那PHP這種直譯的情 06/10 08:46
3F:→ Den3: 況下也適用嗎? 06/10 08:46
4F:→ Den3: 沒事,不好意思,剛剛短路,搞錯重點 06/10 09:14
5F:推 y2468101216: 推好文應該要M 06/10 09:23
6F:推 chan15: 謝謝大大的熱情回應,原理跟使用方式我懂,我想問的是情境 06/10 13:15
7F:→ chan15: 以一般繼承的 class 來講,功能可能多半集中在自己 06/10 13:16
8F:→ chan15: 有些共同 function 去 parent 拿,這是一般的配置 06/10 13:16
9F:→ chan15: DI 的設計是把功能在 Stage 操作,注入不同 class 06/10 13:17
10F:→ chan15: 換 class 等於換 config,而且是有 function 的 config 06/10 13:18
11F:→ chan15: 怎樣的情境才有使用的絕對差異呢,舉例一個問題 06/10 13:20
12F:推 chan15: DI http://pastebin.com/1NFCEW0y 06/10 13:40
13F:→ chan15: abstract http://pastebin.com/nz6u8ceL 06/10 13:41
14F:→ chan15: 這兩個結果一樣,abstract 甚至可以繼承 parent 東西來用 06/10 13:42
15F:→ chan15: 所以我想問這個原則跟使用情境 06/10 13:43
16F:→ banjmin: 重點還是要看需求多複雜,你的例子太小了,其實沒什麼差 06/10 22:50
17F:→ banjmin: 差別可能就是假設你今天面對新需求勢必要繼承另一個class 06/10 22:50
18F:→ banjmin: 語言沒有多重繼承的時候 原本繼承的做法就做不下去了 06/10 22:51
19F:→ banjmin: 你勢必要換成介面的做法 06/10 22:51
20F:→ banjmin: abstract class用的好的例子 可以看看template pattern 06/10 22:53
21F:→ banjmin: 滿足開放封閉原則,看看decorator pattern怎麼使用DI 06/10 23:02
22F:→ banjmin: 不過不管pattern怎麼樣,重點還是你想做什麼功能 06/10 23:02
23F:→ banjmin: 再來談適合的、有彈性的設計,pattern例子通常不能直接套 06/10 23:03







like.gif 您可能會有興趣的文章
icon.png[問題/行為] 貓晚上進房間會不會有憋尿問題
icon.pngRe: [閒聊] 選了錯誤的女孩成為魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一張
icon.png[心得] EMS高領長版毛衣.墨小樓MC1002
icon.png[分享] 丹龍隔熱紙GE55+33+22
icon.png[問題] 清洗洗衣機
icon.png[尋物] 窗台下的空間
icon.png[閒聊] 双極の女神1 木魔爵
icon.png[售車] 新竹 1997 march 1297cc 白色 四門
icon.png[討論] 能從照片感受到攝影者心情嗎
icon.png[狂賀] 賀賀賀賀 賀!島村卯月!總選舉NO.1
icon.png[難過] 羨慕白皮膚的女生
icon.png閱讀文章
icon.png[黑特]
icon.png[問題] SBK S1安裝於安全帽位置
icon.png[分享] 舊woo100絕版開箱!!
icon.pngRe: [無言] 關於小包衛生紙
icon.png[開箱] E5-2683V3 RX480Strix 快睿C1 簡單測試
icon.png[心得] 蒼の海賊龍 地獄 執行者16PT
icon.png[售車] 1999年Virage iO 1.8EXi
icon.png[心得] 挑戰33 LV10 獅子座pt solo
icon.png[閒聊] 手把手教你不被桶之新手主購教學
icon.png[分享] Civic Type R 量產版官方照無預警流出
icon.png[售車] Golf 4 2.0 銀色 自排
icon.png[出售] Graco提籃汽座(有底座)2000元誠可議
icon.png[問題] 請問補牙材質掉了還能再補嗎?(台中半年內
icon.png[問題] 44th 單曲 生寫竟然都給重複的啊啊!
icon.png[心得] 華南紅卡/icash 核卡
icon.png[問題] 拔牙矯正這樣正常嗎
icon.png[贈送] 老莫高業 初業 102年版
icon.png[情報] 三大行動支付 本季掀戰火
icon.png[寶寶] 博客來Amos水蠟筆5/1特價五折
icon.pngRe: [心得] 新鮮人一些面試分享
icon.png[心得] 蒼の海賊龍 地獄 麒麟25PT
icon.pngRe: [閒聊] (君の名は。雷慎入) 君名二創漫畫翻譯
icon.pngRe: [閒聊] OGN中場影片:失蹤人口局 (英文字幕)
icon.png[問題] 台灣大哥大4G訊號差
icon.png[出售] [全國]全新千尋侘草LED燈, 水草

請輸入看板名稱,例如:BabyMother站內搜尋

TOP