少用繼承,多用介面

更新於 2024/12/11閱讀時間約 6 分鐘

承接上一篇文章,現代的物件導向已經走偏了,他就像null pointer,很容易出現不好的設計。自從我深入學習函數式編程後,漸漸發現物件導向的不合理的設計,而學習rust之後更讓我開始討厭物件導向,rust幾乎把所有我認為不好的地方都修正了。這個系列的文章我將會一一比較物件導向與rust的差異。這篇文章將關注於繼承機制。


物件導向的設計方式通常是先預想多個任務或情境,並設計一個物件來統一處理它,之後若是有新的情境,可以藉由繼承來延伸功能。這種設計方式好處是非常直觀且容易擴展,但這反而容易累積各種技術債。設計物件時一般都是以可擴展為前提,但我們往往無法預測它會怎麼擴展,有可能之後的擴展打破了一些原本的假設,使得之前寫的程式邏輯出現錯誤。這種「向後的抽象化設計」很容易出現這種情況,因為我們總是以「這部分的程式碼可以重用」來實作父類別,但並沒有考慮到應該在怎樣的情況下才能使用。正確的設計方式應該要寫明繼承這個類別應該符合哪些規則,也就是關注約束(constraint)而非延展(extension)。抽象化就是對未知的事物建立模型,這個過程很容易會將先入為主的假設帶入其中,而關注約束更容易發現那些未察覺的潛在資訊(unknown knowns),讓你更能夠意識到你的程式邏輯運用了哪些假設。


這種關注約束的設計方式更適合使用介面而非類別來定義規則,尤其是當你想要抽象化的行為不侷限於一種類別時。例如,當你想要設計一個可以連線的物件,但又不想限制在某種情境下運作,你應該設計一個介面Connectable而非抽象類別Connection。介面一般不帶有預設實作,因此本身並不具有重用程式碼的能力。若是要重用程式碼,不應依賴於繼承機制,而是使用高階函式或是組合物件等方法,如此更容易把規則理清。除去延伸功能後,繼承仍可以用來細分類別,也就是讓物件在已知的情境下做出不同的行為,而這個機制應當只在內部使用,不應讓它在你不知道的地方被繼承改寫。


rust的trait system類似於介面,但並不完全一樣。trait(特性)跟介面一樣都是用於描述行為,也一樣都是關注於約束而非延展。實作介面一般需要在定義類別時實作介面的方法,也就是介面是類別的一部分。而trait描述的是特性本身,並不需要在定義類別時實作。trait所描述的特性並不侷限於單個類別,它也可以描述多個類別之間的特性,例如A: Add<B>描述的是A與B之間的加法關係。rust甚至可以為符合某些條件的所有類別實作trait,例如我們可以為所有擁有特性A: Add<A> 的類別A實作A: Mul<uint>。基於以上能力,我們不應該把trait當作類別的一部分,而是特性本身。然而rust把trait的語法設計的跟介面一樣,其實它應該寫作Add<A,B>,也就是「存在一個trait描述A與B之間的加法特性」,編譯器會根據上下文去搜尋合適的trait。trait 的這種設計把類別的定義與trait的定義分開,讓我們可以把不同的關注點分離開來,而非像介面必須綁在類別的定義之上。


rust跟物件導向的另一個很大的不同是rust沒有類似於繼承的子類關係,但是有基於泛型的子類關係。在有繼承特性的程式語言中,當你拿到了一個類別為A的參數,它可能其實是B的物件實體,只是它的類別繼承自A。這種子類關係使得類別無法描述實際的物件實體,迫使我們必須以抽象的方式思考程式邏輯,而非基於實作細節。這種隱藏部分細節的做法讓我們能夠把雜音去除,讓我們專注於更重要的概念與程式邏輯。然而我們沒辦法限制變數只能是哪種實體,有些程式語言甚至沒辦法阻止類別被繼承,就算能也不適用於所有情況,這使得我們需要額外注意上下文才能判斷變數到底是不是延展過的物件。


基於泛型的子類關係則是利用類型參數與類型約束界定類別的範圍,例如List<A> where A: Comparable 代表由所有內容可比較的列表的集合,也就是List<int>, List<string>, List<List<int>> 等類別的聯集(正確來說是indexed family)。他的子類關係建立在約束的強度,例如它是 List<A> where A: Equal 的子類,因為所有可比較的類型都是可以判斷相等的,因此其組成的列表也有子類關係。類型參數明確地表明我們不知道它到底是什麼,只知道它有什麼特性,因此更能區別抽象與實作的邊界。你可以把類型參數想像成某個類別「未知」的部分,比起宣告x: List<Comparable>(變數x是內容可以比較的列表,但我不知道他的內容到底是什麼),不如宣告A: Comparable跟x: List<A>(變數x是內容可以比較的列表,但我不知道他的內容到底是什麼,姑且叫他A)。透過泛型,我們可以把未知的部分串聯起來,並使程式邏輯更加一致。


rust的trait在意義上跟類型有很大的不同,他更像是類型的種類而非一種特殊的類型,因此不能直接宣告變數為 Comparable,必須藉由類型參數的約束描述物件的抽象行為。因此trait用來描述抽象的概念,而型別則用於描述實際的資料結構。這一點跟介面很不一樣,我們一般都會把介面當作一種純抽象類別,因而用類似繼承的概念思考。在trait system中,A: Comparable代表的不是「類型A是類型Comparable的子類」,而是類型本身是Comparable裡的一個類別。Comparable可以看作是類別的集合,而我們透過這些集合界定我們想要的類型,就像是我們可以透過類型界定我們想要的物件,因此trait被稱為二階類型(2-types, kinds)。正因為它們不是包含關係(⊆)而是隸屬關係(∈),抽象的概念才能完全從類別獨立出來。

avatar-img
4會員
28內容數
這不是教你如何從物件導向到函數式編程的入門教程。我會深入探討物件導向與函數式編程的差異,並討論為什麼你應該使用函數式編程並徹底放棄物件導向。
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
have bear的沙龍 的其他內容
在現代,物件導向雖然仍是主流,函數式慢慢得到關注。物件導向並不適合所有的程式邏輯,但在像是Java的物件導向的程式語言中,幾乎所有值都被當作物件,因此在一些情境下Java寫起來會非常冗余。物件導向流行的原因大概是因為它的思考方式比較符合我們對於世界的認知,但邏輯推理與解決問題的方式卻不一定符合我們的
我學習程式語言的動機並不是想要做什麼遊戲,而是單純覺得很有趣。除去國小自己寫過網頁的經歷,我
What Color is Your Function? 一文中 Async function 被比喻成「紅色函式」 紅色函式不能在普通的函式裡(即「藍色函式」)使用 因此紅色具有感染性 定義函式之前必須先決定是否要染成紅色 作者不喜歡這種麻煩的規則 但我認為這種麻煩是有道理的
'方格子在 linux/firefox 上的 bug 超煩 '若在每行第一句打中文會被吃掉 'Ctrl+V還會複製貼上之後的文字貼上之後的文字
在現代,物件導向雖然仍是主流,函數式慢慢得到關注。物件導向並不適合所有的程式邏輯,但在像是Java的物件導向的程式語言中,幾乎所有值都被當作物件,因此在一些情境下Java寫起來會非常冗余。物件導向流行的原因大概是因為它的思考方式比較符合我們對於世界的認知,但邏輯推理與解決問題的方式卻不一定符合我們的
我學習程式語言的動機並不是想要做什麼遊戲,而是單純覺得很有趣。除去國小自己寫過網頁的經歷,我
What Color is Your Function? 一文中 Async function 被比喻成「紅色函式」 紅色函式不能在普通的函式裡(即「藍色函式」)使用 因此紅色具有感染性 定義函式之前必須先決定是否要染成紅色 作者不喜歡這種麻煩的規則 但我認為這種麻煩是有道理的
'方格子在 linux/firefox 上的 bug 超煩 '若在每行第一句打中文會被吃掉 'Ctrl+V還會複製貼上之後的文字貼上之後的文字
你可能也想看
Google News 追蹤
Thumbnail
*合作聲明與警語: 本文係由國泰世華銀行邀稿。 證券服務係由國泰世華銀行辦理共同行銷證券經紀開戶業務,定期定額(股)服務由國泰綜合證券提供。   剛出社會的時候,很常在各種 Podcast 或 YouTube 甚至是在朋友間聊天,都會聽到各種市場動態、理財話題,像是:聯準會降息或是近期哪些科
Thumbnail
❏ 專注力是知識工作中最珍貴的資源,應該用來產出有效成果。 ❏ 常存下文章後再看,結果常常不了了之,失去當時的感受,浪費時間與注意力。 ❏ 讀完文章後,立即用語音轉文字記錄,不僅加強記憶,還能確認是否真正理解內容。
Thumbnail
第6屆品牌金舶獎歷經數月選拔,最終評選出31家傑出企業,於8/22下午盛大舉辦頒獎典禮,而亞家生技在眾多品牌中脫穎而出,獲得「綠色永續組」肯定。亞家生技創辦人吳坤烈博士除了感謝評審遠見,也表示將持續耕耘再生醫療領域,為綠色永續而努力。
Thumbnail
家中冷氣機常常需要清潔,使用驅塵氏冷氣清潔劑能有效消除冷氣機黴味,提升效能,改善室內空氣品質。本文分享了驅塵氏冷氣清潔劑的特色、使用方式和注意事項,讓您瞭解如何清潔冷氣機,使您和家人呼吸更加清新的空氣。
Thumbnail
人生來到了樂齡階段,你會發現銀行帳戶其實也是人生歷程的見證,隨著工作的轉換、房貸辦理、投資理財...,在不知不覺中可能累積出了多家銀行的帳戶,但實際上真正有使用的帳戶卻很少,雖然銀行不會因為這些閒置的帳戶向我們收取保管費,但未來有一天將會成為家人的麻煩。
承接上一篇文章,現代的物件導向已經走偏了,他就像null pointer,很容易出現不好的設計。自從我深入學習函數式編程後,漸漸發現物件導向的不合理的設計,而學習rust之後更讓我開始討厭物件導向,rust幾乎把所有我認為不好的地方都修正了。這個系列的文章我將會一一比較物件導向與rust的差異。這篇
Thumbnail
可能包含敏感內容
5W是大家很常會用到的方式 之前有一篇有提到 問題分析跟職能的大小T很像 使用樹狀圖的What、Why、How三個層級 也提到Why、Why、Why的方式來深入探討問題 但是 在運用上還是要看問題狀況還選擇 Why偏向於找出過去發生的原因 How偏向於找出未來處理的方法 兩個是不同
Thumbnail
【記者許家源/雙北報導】        臺北市青少年發展暨家庭教育中心響應10月10日世界心理健康日,於10月14日(星期六)與中華心理衛生協會合作辦理「兒少心理韌性書目發布會」暨書展,當天將進行年度推薦書目發布,並設有心理韌性圖書閱讀區,也邀請不同學校至現場進行心閱讀校園方案展示,歡迎各界踴躍參
Thumbnail
❤️粉紅泡泡!讓我們為【初戀】買單! 回頭梳理這段筆記,他和我那幾年都處在【人生最低谷】,初戀被【現實面】上,重重地打臉!粉紅泡泡讓我們,都為自己的初戀,狠狠地買單!但是,你說再來一次,小倉鼠會如何選擇?我會說,【高中姐妹淘】和【初戀】,仍然會是我的優先順位,因為,一直到現在,我還是很感謝自己有過,
Thumbnail
❤️閱讀之後,如何化【知道】為【做到】呢? 這次挑了這本《少就是力量》,其實,這本書從買回家,反反覆覆被我看了好多次,反覆看原因是我內心一直有想培養的習慣,但是,想馬上養成並不容易,剛開始以為這一本斷捨離的書,可以協助解決內心的困擾,後來發現減法的道理,套在看待人生也是可以,但是,人生就是這樣,很多
Thumbnail
產品規劃流程時,除了要思考如何優化使用者體驗,也要思考如何減少用戶阻力,讓用戶在最「簡單、快速」的情境下完成任務,這篇想整理我看的到減少用戶阻力的方法。
Thumbnail
*合作聲明與警語: 本文係由國泰世華銀行邀稿。 證券服務係由國泰世華銀行辦理共同行銷證券經紀開戶業務,定期定額(股)服務由國泰綜合證券提供。   剛出社會的時候,很常在各種 Podcast 或 YouTube 甚至是在朋友間聊天,都會聽到各種市場動態、理財話題,像是:聯準會降息或是近期哪些科
Thumbnail
❏ 專注力是知識工作中最珍貴的資源,應該用來產出有效成果。 ❏ 常存下文章後再看,結果常常不了了之,失去當時的感受,浪費時間與注意力。 ❏ 讀完文章後,立即用語音轉文字記錄,不僅加強記憶,還能確認是否真正理解內容。
Thumbnail
第6屆品牌金舶獎歷經數月選拔,最終評選出31家傑出企業,於8/22下午盛大舉辦頒獎典禮,而亞家生技在眾多品牌中脫穎而出,獲得「綠色永續組」肯定。亞家生技創辦人吳坤烈博士除了感謝評審遠見,也表示將持續耕耘再生醫療領域,為綠色永續而努力。
Thumbnail
家中冷氣機常常需要清潔,使用驅塵氏冷氣清潔劑能有效消除冷氣機黴味,提升效能,改善室內空氣品質。本文分享了驅塵氏冷氣清潔劑的特色、使用方式和注意事項,讓您瞭解如何清潔冷氣機,使您和家人呼吸更加清新的空氣。
Thumbnail
人生來到了樂齡階段,你會發現銀行帳戶其實也是人生歷程的見證,隨著工作的轉換、房貸辦理、投資理財...,在不知不覺中可能累積出了多家銀行的帳戶,但實際上真正有使用的帳戶卻很少,雖然銀行不會因為這些閒置的帳戶向我們收取保管費,但未來有一天將會成為家人的麻煩。
承接上一篇文章,現代的物件導向已經走偏了,他就像null pointer,很容易出現不好的設計。自從我深入學習函數式編程後,漸漸發現物件導向的不合理的設計,而學習rust之後更讓我開始討厭物件導向,rust幾乎把所有我認為不好的地方都修正了。這個系列的文章我將會一一比較物件導向與rust的差異。這篇
Thumbnail
可能包含敏感內容
5W是大家很常會用到的方式 之前有一篇有提到 問題分析跟職能的大小T很像 使用樹狀圖的What、Why、How三個層級 也提到Why、Why、Why的方式來深入探討問題 但是 在運用上還是要看問題狀況還選擇 Why偏向於找出過去發生的原因 How偏向於找出未來處理的方法 兩個是不同
Thumbnail
【記者許家源/雙北報導】        臺北市青少年發展暨家庭教育中心響應10月10日世界心理健康日,於10月14日(星期六)與中華心理衛生協會合作辦理「兒少心理韌性書目發布會」暨書展,當天將進行年度推薦書目發布,並設有心理韌性圖書閱讀區,也邀請不同學校至現場進行心閱讀校園方案展示,歡迎各界踴躍參
Thumbnail
❤️粉紅泡泡!讓我們為【初戀】買單! 回頭梳理這段筆記,他和我那幾年都處在【人生最低谷】,初戀被【現實面】上,重重地打臉!粉紅泡泡讓我們,都為自己的初戀,狠狠地買單!但是,你說再來一次,小倉鼠會如何選擇?我會說,【高中姐妹淘】和【初戀】,仍然會是我的優先順位,因為,一直到現在,我還是很感謝自己有過,
Thumbnail
❤️閱讀之後,如何化【知道】為【做到】呢? 這次挑了這本《少就是力量》,其實,這本書從買回家,反反覆覆被我看了好多次,反覆看原因是我內心一直有想培養的習慣,但是,想馬上養成並不容易,剛開始以為這一本斷捨離的書,可以協助解決內心的困擾,後來發現減法的道理,套在看待人生也是可以,但是,人生就是這樣,很多
Thumbnail
產品規劃流程時,除了要思考如何優化使用者體驗,也要思考如何減少用戶阻力,讓用戶在最「簡單、快速」的情境下完成任務,這篇想整理我看的到減少用戶阻力的方法。