PHP 板


LINE

看板 PHP  RSS
聊过了类别的封装,我们要继续实例讨论物件导向的第二特性, 也就是所谓扩充的能力。 这有点像是在玩游戏, 假设你在游戏里操作着一只小猪,这只小猪有一个特技叫做「吃」, 每次当你遇到某个谜题时,都必需让小猪「吃」的能力成长, 可能需要吃铁,吃火,吃土…等等, 而每当你拿到一种新的「吃」的能力,小猪的封号也会随之改变。 上面这个情景很类似我们对於物件导向扩充的描述, 让我们继续延伸前一篇的程式内容,把这个游戏情景给套用进去 目前我们手上持有的是一个叫 dataHandler 的类别, 里面一共具有三种不同的输出方式,分别是 output_select output_list output_radio 仔细想想,每次都我们输入资料产生出一个物件时, 实际上真正会使用到的输出行为都只是三种中的其中一种, 那换个角度,我们是否能让这个处理资料的类别具有合适的扩充能力? ok,没有命题就不会有 fu,我们需要一个假设性的命题, 如果当你在执行这个案子的时候,你敏锐的触感神经已经预计到, 客户很有可能又额外提出六种输出方式和三种统一验证, 那这个时候要做什麽就很明确了, 我们需要这个类别具有输出上的可扩充性,套用故事里的情境, 也就是这个小猪(类别),需要可以增加不同的吃(输出)的能力。 当然最简单的方法就是增加类别内的 output_* 函式, 反正客户要几个就加给他几个, 但也可以这样思考,我们有没有可能把整个扩充方式从扁平改成立体? 既然现在面对的扩充是针对「输出」这件事, 那就来规规矩矩把输出部份给抽象化, 於是原本的类别会变成: class dataHandler { var $_data = Array (); function __construct ($data) { (省略) } function data_remove_sexy () { (省略) } function data_check_add_admin () { (省略) } function output () { // 空的 } } 仔细看,三种不同的 output 此刻只剩下一种, 而且这个 output 函式还是个货真价实的空荡荡的函式,里面没有半行程式码, 为什麽呢? 因为我们要从原本「在类别内的横式扩充」, 改成「藉由类别衍生所产生的直式扩充」, 刚刚上面这个 class dataHandler 其实只是一个初始类别, 真正可以拿来使用的会是下面这三个子类别: class dataHandler_OutputSelect extends dataHandler { function output () { // 输出 select 的程式码 } } class dataHandler_OutputList extends dataHandler { function output () { // 输出 list 的程式码 } } class dataHandler_OutputRadio extends dataHandler { function output () { // 输出 radio 的程式码 } } 如果你需要进行一个 select 输出,你会这样使用: $data = mysql_fetch_* ($sql); $dh = new dataHandler_OutputSelect ($data); $dh->output (); 如果今天是一个 radio 输出,你会这样使用 $data = mysql_fetch_* ($sql); $dh = new dataHandler_OutputRadio ($data); $dh->output (); 我知道板友们一定会开始有种被骗的感觉,这跟 $dh->output_select () 和 $dh->output_radio () 的作法有什麽不同?而且感觉还多写了一堆 code(额外三个 class)! 请容小弟解释一下,这两种不同作法当中存在着很巨大的差异, 其一是这样的程式在扩充上会更清楚明了, 因为往往一个类别不会只有单个函式需要做扩充, 如果同一个类别内存在着一堆相似又不同的函式,那真的是阅读和维护上的痛苦。 其二是这样的作法让物件本身操作具有了一致性, 只要是 dataHandler 的子类别, 你永远知道它具有一个关键的函式是 output,而且可以毫不犹豫地呼叫它, 这点非常重要,但我们会在下一篇里面再来详谈, 因为也就是垂直扩充的物件具有了操作的一致化,第三个物件导向特性才得以成立 其三,则是一个比较难以理解的概念,那就是「决策点」的不同, (这部份如果看不懂也没有太大关系,因为需要有经验才比较能体会) 如果要打个比方,「决策」的概念比较像是篮球赛里面, 你有整整 30 秒可以出手,跟被强迫在最後 0 秒出手的不同是一样的, 这样讲好了, 当我们在尝试把一整个程式逻辑慢慢拆解成几种类别时, 有的类别存在周期会很长,有的则是很短, 也就是说, 有些类别会在你程式一开始的时候就已经产生物件,并持续使用到最後, (最常见的就是封装成类别的资料库操作) 有的类别则是「当下产出物件」-「当下使用」而已, (就像是我们刚刚的资料输出类别) 所以此时你在设计程式流程时会有两个选择, 从类别 new 出物件时做决策, (像决定你要使用哪一种输出类别, dataHandler_OutputSelect 还是 dataHandler_OutputRadio) 或是在最後函式呼叫时做决策, (像决定你要使用哪一种输出函式, dataHandler 下的 $dh->output_select 还是 $dh->output_radio) 这当中各有各的使用时机,就端看你整体程式的运作流程要怎麽设计来决定, 其中很多复杂的运用同样也是在导入了设计模式之後才会发现的。 讲到这里,物件导向的第二特性 - 继承也差不多讲完了。 关於继承的详细定义和宣告方式,不熟悉的板友可以再去看一下, 这部份小弟就不赘言了。 -- 头痛中…(炸) --



※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 114.45.241.224
1F:推 chenstin:推! 07/30 22:01
2F:推 weiyucsie:推 07/30 22:44
3F:推 roga:推 :P 07/30 22:57
4F:推 bobju:推! 07/31 10:12
5F:推 hertz:NICE 07/31 18:40
6F:推 qmo668:推! 10/02 01:47







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

请输入看板名称,例如:WOW站内搜寻

TOP