OOAD 板


LINE

※ 引述《SpiritKnight (无心)》之铭言: : 板上的前辈好我也想学习学习物件导向,我是电子系的,却对程式比 : 较有兴趣,但是因为本身不是资讯底子出身,所以对程式了解并没有 : 很深,都是上上课,学学指令,基本的什麽For,Do,If...等等的这些 : 学到都烂了,但是每当自己想提起手来写个程式的时候,小程式易写 : ,但是稍大一点的就像撞了墙一样,怎麽都感觉怪怪的,可是该会的 : 指令就明明都会,却不知道问题出在哪,後来一直有人建议我去了解 : 物件导向(虽然我不知道主因是否在此),但是一直常听到这个词,後 : 来不论是去上网查还是去书局翻书,发现不只"物件导向"这四个字我 : 认识,书里的每个字我也都认识,但是组合起来却似乎没有办法那麽 : 熟悉它到底在说什麽,通常不外乎就是一堆理论,想请教板上的高手 : ,有什麽书或是网站,是对物件导向深入浅出,并且有将物件导向与 : 传统的程式设计方式做相互比较的书,适合对物件导向很没概念的人 : 看的书吗? 谢谢各位前辈~ 看到这篇实在是有感而发 小弟开始接触写程式也是半年内的事 更何况写的code没几行(最初接触原因是为了parse某个网站资讯) 最近毕业後 上个月才开始认真的研读程式语言和物件导向(因为真的有兴趣) 我发现「物件导向」四个字真的是个屁 很多人举「汽车」例子来解释物件 接着讲解实例(instance)和继承(inheritance) 然後封装(encapsulation)、抽象化(abstraction)和多型(polymorphism)则是含糊带过 初学者根本听不懂 这种说明真的是模糊了Object-Oriented的精神 到最後就是错误的使用OO 而不断的subclass和创造物件来撰写程式 这些完全没办法让学习者了解OO的真正使用方式 只是为了解释而解释 这让我学习OO的路上绕了一大段路 直到我念了欧莱礼出版的「深入浅出物件导向分析与设计」後才恍然大悟 (虽然这本书没有讲Object到底是什麽,接下来的内容完全是个人体悟,请多指教) 真的很希望能将Object-Oriented programming翻译成「以『目的』为取向的撰码」 我认为Object-Oriented: 是为了管理操作而将程序式撰码(procedural programming)分成许多目的(object)撰码 而不是为了物件(object)存在而去产生属性(property)方法(method) 简单的说 OO是为了「管理」程式而将程式码和资料依照目的(Object)分类(Class)管理 而不是为了要「模拟」某种类别(Class)物件(Object)所应该具备的特质(属性及方法) 因此程式码之属性(变数)及方法(功能)是为了同一目的而存在同一Object中 方便管理 而任何需要「管理」的 一定是个大东西 所以越大型程式用正确的物件导向越容易维护 OO最主要的精髓并不是在於继承 而是在於封装 封装(encapsulation)就是将程式码分开到特定的class 而这些程式码具有相同的目的 透过封装 将程式码依照不同的目的分门别类(class) 以方便使用与管理 透过封装 将不同的资料得以分开操作(instance) 以方便使用与管理 透过封装 可以将固定的程式码和经常变动的程式码分开 以方便管理和使用 继承(inheritance)是为了abstration而存在 **abstration大多翻译为「抽象化」但是我会重新翻译为「提取」 **由於我对於abstration这个字的意义有不同解读 因此本文关於这字的解释会有所不同 「提取」是将重复的程式码抽出来 封装一个class里面 简单的说是要避免程式码的重复 再藉由继承来分配到必须拥有这些特性的class当中 换句话说使用继承的目的是为了提取 将不同目的中 拥有共同的目的之特性抽取出来管理 而继承不是为了创造新的类别或物件 因此 没有需要abstration的理由 就没有需要inheritance的理由 多型(Polymorphism)是传递多种类别的接口 以达许多片段程式码的固定 **多型的解释需要code或图来帮助理解 但是这里只做文字解释(原谅我偷懒) 在继承当中 有个很重要的功能 就是覆写(overwrite) 也就是可以修改父类别的method 当你的程式码有某method都具有同源(homogenous,即本质相同)但有些许差异或不同行为 **用生物学眼光来解释 就是同源基因 但基因序列编码不同 =>希望能帮助生物人理解 Orz 覆写原本的目的是为了可以在继承大部分的父类别的程式码 又可保有修改些许功能的弹性 但是只为了覆写一些方法 却没有新增新的方法 而去subclass大型Object是个很蠢的作法 > 举例来说 同样是「飞(fly)」的方法 但是「动物类别」飞行的方法有很多种 > 但是无论你之後创造了什麽动物(鸟、蟑螂、飞鼠等翅膀或飞行模式并不同) > 你都希望在你创造的「动物类别」中有一个「飞(fly)」的方法可以呼叫 > 初学者很容易就针对这个动物类别subclass出鸟、蟑螂等多个子类别 > 然後直接覆写「飞」的功能 (如果设计的动物不会飞 则将它覆写为没有功能) > 这种就是为了「物件」的存在而去「继承」来写OO的方式 > 只为了「覆写」却没有新增任何功能而将类别进行subclass不是一个好的管理程式方式 > 较好的作法是将「飞行」视为一种「目的」而将其封装出来成为一个类别 > 该类别中只有一个「飞」的方法 > 然後针对「飞行」类别进行subclass(鸟类飞行、昆虫飞行、飞鼠飞行、蝙蝠飞行等) > 覆写subclass中的「飞」的方法 > 最後在「动物」类别中 建立一个属性为「飞行」型态 > 然後只要在原先「动物」的类别中的「飞」去呼叫「飞行」类别中的「飞」 > 这样就可以不必在更改任何「动物」的code或是subclass > 然後在创造实例(instance)後设定飞行的类别是何种「子类别」 **以上举例不懂没关系 因为我自己都快看不懂了 Orz 重点是 当你subclass的东西越庞大 就越容易出错或难以维护 而利用多型 就是将同源(同样名称)但不同功(功能)的方法 抽离并封装出来 利用inheritance/abstraction这样的关系 来重新覆写子类别的方法 这样只要在原先类别固定呼叫抽离封装出之类别的方法 实作则在该子类别当中 而只要在创造实例时决定呼叫哪种子类别(设为变数)即可 这样就可以固定原先类别的程式码 (以後要新增飞行方法都可以不必更改到动物类别) 也可避免对大型类别进行过度的subclass了 至於我认为什麽是Object? 其实前面说的很清楚了 Object就是某种「目的」 所有属於这个目的的方法、变数当应该分类(classify)到同一个类别(class)中 我将这些目的(Object)可以分为下面几种: *资料分类目的: 此Object是为了存放不同实例(instance)的资料 而将这些相关变数放在一起 而其应该包含的方法应该都是与存取(accessor)或操作这些instance variables有关 这样可以在实作时将不同实例的的资料分开来管理和操作 其他无关的方法或属性则应该封装出来 *方法分类目的: 主要是操作相同目的之method 分类在同一类别中 而其所带有的变数(或称属性)则是为了这些方法所需纪录保存的参数 此Object的存在 最主要是提供不同的Object可以呼叫同样的功能 *架构固定目的: 简单的说 就是前两者Object中需要实行abstration出来的Object 存在的理由只有两种 1.将相同的方法和属性提取出来 2.为了使用多型 其目的都是为了避免重复程式码以减少需要的管理 将「固定」之物抽离出来固定 让变化的部份在继承中实作 (另:封装亦是将「变化」之物抽离出来管理) 因此这些「固定」出来的Object 即会变成一种较大的架构/骨架(因为几乎不会变动) 也就是因为主要利用abstraction/inheritance的「结果」来决定固定的架构 由於使用继承比使用封装来处理「变化」部份的程式码要来得简单 造成大部分的人在学习或使用OOP的时候 认为subclass才是OOD的精髓 却忘了OO一切都是用封装来处理「不同本质的变化之物」 这样有点本末倒置 而继承只是用来处理「相同本质的变化之物」也就是子类别和父类别本质上是相同的 (以前面提到的例子来说 「动物」和「飞行」在本质意义上是不同的 也就是在撰码时要修改的原因和存在目的并非一致 所以会封装出来再利用多型特性结合) 藉由委派(delegation)、聚集(aggregation)、合成(composition)等协同操作方式 是将不同的目的程式码(objects)整合成一个真正完整功能的物件(object) 所以良好的OOD 1.应该是要把不同目的之程式码分开 一种Object应该只有一种存在的目的 2.不会有任何重复的程式码 任何相同目的重复程式码都必须抽离出来 若是同一物件多个方法会用到相同程式码 则抽离出来成为同物件下独立的方法 若是多个物件会用到相同程式码 则抽离出来成为独立一个的物件下的方法 3.将应该十分固定及时常变更的程式码分开 即使目的相同 4.当一个理由需要新增或改写程式码时 需要维护或改变的Object应该是非常少的 而不是分散在四处都需要改变 减少程式发生错误的可能 才不会牵一发动全身 需要改变的地方越少 越容易维护和除错 5.适当的将程式码分配到不同Object可以快速了解程式的操作 能帮助了解整个程式架构 换句话说汽车(car)应该是由多个Objects协同组成 而不该把car设计成一个单独的Object(除非程式很小而且你又很懒得拆开来) **如何拆解请参考欧莱礼出版的「深入浅出物件导向分析与设计」p393-395 -- 以上是我对Object-Oriented的浅见 请多多指教 :) --



※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 163.13.42.121 ※ 编辑: leondemon 来自: 163.13.42.121 (10/25 01:48)
1F:推 andrew43 :受用, 非常感谢. 10/25 01:43
※ 编辑: leondemon 来自: 163.13.42.121 (10/25 03:03)
2F:推 idleidle :先推後看 10/25 11:18
3F:→ adrianshum :最後一段只令我觉得你一知半解. car 是一个 class 10/25 17:57
4F:→ adrianshum :还是让由多个obj 组合, 诚如你所说, 该看你的 car 10/25 17:57
5F:→ adrianshum :目的是什麽. 这样没头没尾的说 "car 是一个obj 是错" 10/25 17:58
6F:→ adrianshum :实在不能苟同 10/25 17:58
7F:→ leondemon :我没说"car 是一个obj 是错"吧 =.= 10/26 11:44
8F:→ leondemon :我是说car应该要由多个Obj组成 除非没有理由要分开 10/26 11:44
9F:→ leondemon :举Car的例子 是因为它常会被视为"物件" 而对它撰码 10/26 11:50
10F:→ leondemon :如果用"物件"的思维 很容易就把所有程式码往它里面塞 10/26 11:51
11F:→ leondemon :但如果用"目的"去思维 就会重新思考程式码的封装方式 10/26 11:53
12F:→ leondemon :Object翻译成"目的"或"主题"会比"物件"提供思考帮助 10/26 11:55
13F:→ qrtt1 :如果不用他原先该有的想法去思考, 10/26 13:07
14F:→ qrtt1 :要同时扭曲很多解释的方式, 这样太过间接了 10/26 13:07
15F:→ TeaEEE :虽然打了很多字 不过不是很同意你很多的看法 10/26 17:56
16F:→ kanandg1 :要如何解释实作介面(或继承虚拟类别)呢? 10/27 16:48
17F:→ kanandg1 :他们没有程式码,不能算code 的reuse吧? 10/27 16:49
18F:→ leondemon :很欢迎大家指教与讨论 因为我也是还在学习! 10/27 19:15
19F:→ H45 :回文回文回文回文回文回文回文回文回文回文回文回文 10/27 20:19
20F:推 Davidjcan :我也是刚学习,我觉得原po写的不错 10/27 21:09
21F:推 adxis :有Aspect Oriented的味道 10/28 20:37
22F:推 adrianshum :"car...协同组成", "不该...单独的 Object" 10/29 11:39
23F:→ adrianshum :所以我才说, 视乎你设计 car 的目的是什麽, 没有应 10/29 11:40
24F:→ adrianshum :不应该协同组成. 另外, 我觉得把 object 想成目的才 10/29 11:41
25F:→ adrianshum :有问题. 建议你去看看 AOP, 那才真的是以目的出发. 10/29 11:41
26F:→ adrianshum :倒是我赞同, 定义 class 的时候, 该把每种 "目的" 10/29 11:48
27F:→ adrianshum :细分, 才能避免你提到那种 "通通都包" 的 class 10/29 11:49
28F:推 aecho :看到这麽长的文章还蛮感动的~~先推一下 11/04 22:19
29F:推 twntwn :不太同意, 物件导向是透过对真实世界的塑模来填补 12/16 05:52
30F:→ twntwn :从问题领域到解决方案领域间的gap.的一种方法论. 12/16 05:54
31F:→ twntwn :ood是物件导向流程中的一项活动,目的是导出解决方案, 12/16 05:56
32F:→ twntwn :有关抽像封装等设计物件的技术,OCP,LSP,DIP,SRP.ISP 12/16 05:58
33F:推 twntwn :可以去了解一下,因该会让你修正一下目前的想法。 12/16 06:01
34F:→ leondemon :谢谢大家的指教 我也只是OO初学者 我会努力上进的! 01/11 21:11
35F:推 larrywhy :好文推 仔细琢磨ing 04/09 13:55







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

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

TOP