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/cn.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灯, 水草

请输入看板名称,例如:Boy-Girl站内搜寻

TOP