軟體工程筆記 | method chaining / fluent interface 讓你的代碼更容易理解和使用

更新於 2023/08/03閱讀時間約 8 分鐘

某次請 GPT 幫我把原本要作為訊息使用的代碼封裝起來,它也完美完成
但意外的他給了我一個從沒看過的寫法
簡化後像是如下

from typing import Self

class MessageBuilder:
def __init__(self):
self.message = ''

def add_line(self, line: str) -> Self:
self.message += line + '\n\n'

# why return self ??
return self

def build(self) -> str:
return self.message


我的疑問是為什麼明明我更改物件狀態,卻還是要回傳物件本身(self)呢?
研究後才知道是為了實現 fluent interface(流暢接口) 所以使用 method chaining (方法鏈) 的形式來設計

這種模式可以使代碼更具可讀性,並使其看起來更像自然語言。

舉個例子

例如,以下是使用 `add_line` 的典型用法:

message_builder = MessageBuilder()
(
message_builder
.add_line("line 1")
.add_line("line 2")
.add_line("line 3")
)


但如果 `add_line` 不返回 `self`,那麼每次調用 `add_line` 方法都需要單獨的一行代碼:

message_builder = MessageBuilder()
message_builder.add_line("line 1")
message_builder.add_line("line 2")
message_builder.add_line("line 3")


雖然兩者做相同的是,但是讀起來的流暢程度和優雅程度就有點差別了
這就是使用 fluent interface (返回 self )的好處。

補充

方法鏈(Method Chaining)

方法鏈接是一個編程技巧,它允許對同一個對象進行多個操作調用,而不需要每次調用都引用該對象。通過方法鏈接,可以在同一條語句中鏈接多個方法調用。通常,每個方法調用返回對象的參考,使得可以繼續調用該對象的其他方法。

這個技巧通常讓程式碼變得更簡潔、更易讀。

方法鏈的好處:
1. 讓調用過程更接近自然語言。
2. 把原本參數列表複雜的方法化作多個參數列表簡單的方法來使用。
3. 減少不必要的代碼量。

這個三點都是有益於開發的,所以方法鏈的存在很有意義。

以上第二點再舉個更具體的例子:把原本參數列表複雜的方法化作多個參數列表簡單的方法來使用

沒有使用方法鏈

假設你有一個 Computer 類,你可以用一個方法來設置所有屬性:

class Computer:
def __init__(self, processor, memory, storage, graphics):
self.processor = processor
self.memory = memory
self.storage = storage
self.graphics = graphics

def specs(self):
return f"Processor: {self.processor}, Memory: {self.memory}, Storage: {self.storage}, Graphics: {self.graphics}"

my_computer = Computer('Intel i7', '16GB', '512GB SSD', 'NVIDIA GTX 1080')
print(my_computer.specs())


這個方法可能造成代碼難以閱讀和維護,特別是當參數變得更多或更複雜時。

使用方法鏈

你可以使用方法鏈,將每個設置拆分為獨立的方法:

class Computer:
def __init__(self):
self.processor = None
self.memory = None
self.storage = None
self.graphics = None

def set_processor(self, processor):
self.processor = processor
return self

def set_memory(self, memory):
self.memory = memory
return self

def set_storage(self, storage):
self.storage = storage
return self

def set_graphics(self, graphics):
self.graphics = graphics
return self

def specs(self):
return f"Processor: {self.processor}, Memory: {self.memory}, Storage: {self.storage}, Graphics: {self.graphics}"


my_computer = (
Computer()
.set_processor('Intel i7')
.set_memory('16GB')
.set_storage('512GB SSD')
.set_graphics('NVIDIA GTX 1080')
)
print(my_computer.specs())


Python 有可以指定參數的寫法,所以我覺得還好,但是當我用 Java 又要再 function 中傳入多個參數時候就有點痛苦了
不過同時也造成複雜度增加,我覺得還是要看情境使用,並不適合用在每個情況
如果你的 function 需要傳入那麼多參數,其實可以把他包成一個物件,或是看看是不是真的需要


限制:

方法鏈的一個限制是,只能用在不需要返回其他值的方法上,因為你需要返回self 對象。即使Python支持用一個return語句返回多個值,也可能無法解決這個問題。


流暢接口(Fluent Interface)

流暢接口是一種編程接口設計方法,使得對象的使用更符合自然語言的結構,提高了程式碼的可讀性和可維護性。流暢接口通常使用方法鏈接來實現。

流暢接口的目標是讓程式碼的讀者能夠更容易理解程式的功能。流暢接口通常用在建構器模式、查詢建立或任何你想以更描述性、自然的方式表示的地方。

總結

方法鏈接和流暢接口在許多現代編程語言和框架中都有使用。這兩個概念有時互相重疊,因為流暢接口通常使用方法鏈接來實現。使用這些技巧可以提高程式碼的可讀性和維護性,使得編碼更符合人類語言的結構。這對於在專案中協同工作的團隊尤為重要,因為它可以讓每個人更容易理解和使用代碼。

參考資料

對我來說 人生就是一個遊戲 活得開心,活得漂亮,活得成功,活得有意義 都是這場遊戲的一個個任務 我想要把這個遊戲打通關 在這裡我會分享一些我自己的經驗 把遊戲打通關的一些技巧 打通關的過程 和我自己發現的小 bug,或捷徑 遇到的喜怒哀樂 遇到的困難 遇到的挫折 歡迎大家一起來摸透和想受 這場人生遊戲
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
本文靈感來自:How to Document Your Code Like a Pro 以下範例程式均為 Python 推薦插件:better comment 前言 程式碼的有效文件化是編程最重要的部分之一 Python 提升可讀性有以下方式: 註釋 類型提示 文檔字串 這些實踐可以提高程式碼的可讀
在程式設計中,我們通常會遇到一個問題: 何時應該使用具有方法的類別,何時應該在模組中使用函式? 如果選擇不當,你的程式碼可能比需要的更複雜,這使得維護更困難 首先,我們需要更好地理解函式和類別的差異。 函式接收輸入參數,然後進行一些操作,並返回結果。你可以將這個結果傳遞給其他函式。在像Haskell
本文靈感來自:How to Document Your Code Like a Pro 以下範例程式均為 Python 推薦插件:better comment 前言 程式碼的有效文件化是編程最重要的部分之一 Python 提升可讀性有以下方式: 註釋 類型提示 文檔字串 這些實踐可以提高程式碼的可讀
在程式設計中,我們通常會遇到一個問題: 何時應該使用具有方法的類別,何時應該在模組中使用函式? 如果選擇不當,你的程式碼可能比需要的更複雜,這使得維護更困難 首先,我們需要更好地理解函式和類別的差異。 函式接收輸入參數,然後進行一些操作,並返回結果。你可以將這個結果傳遞給其他函式。在像Haskell
你可能也想看
Google News 追蹤
Thumbnail
*合作聲明與警語: 本文係由國泰世華銀行邀稿。 證券服務係由國泰世華銀行辦理共同行銷證券經紀開戶業務,定期定額(股)服務由國泰綜合證券提供。   剛出社會的時候,很常在各種 Podcast 或 YouTube 甚至是在朋友間聊天,都會聽到各種市場動態、理財話題,像是:聯準會降息或是近期哪些科
Thumbnail
紀錄一下2020年以來做過的斜槓(不務正業)的工作有哪些,包含自創line貼圖、APP開發還有錄製podcast。比較慘的就是沒賺到啥錢,但也沒有什麼損失就是了。
Thumbnail
首先我接受了一些企業的面談邀約,包含才式、紅樓與麗臺,本文會記錄我在這三間公司面試的過程。
Thumbnail
首先我接受了一些企業的邀約,包含禾向、博訊、弘一與鯨躍,本文會記錄我在這四間公司面試的過程。
Thumbnail
煩惱不知道該用什麼數位筆記嗎? Heptabase 會是你最佳的選擇。Heptabase 在心智圖 、網絡、區塊間取得絕佳的平衡。簡樸直觀的設計讓你很專心的寫筆記,絕對是高效的知識工作者必備的工具之一。
從一開始的JavaScript,到後面HTML和CSS,雖之前有稍微碰過一點其他線上課程的內容,但AC系統性的教學,一個單元一個單元循序漸進的上課方式滿適合我的,有一種在打遊戲破關的感覺,非常享受。 已經報名學期二了,期望自己在學期二能夠維持學習進度,持續精進! 謝謝AC!
Thumbnail
如果有在接觸軟體開發產業,很常見的一個說法是非本科(資訊、工程背景)的工程師底子差,做出來的東西很糟糕之類的。然而,事實真的是這樣嗎?又或者說,我們能夠如何解決這樣的問題?
Thumbnail
關於Bezos的「API命令」,這可說是科技史中堪稱是教科書等級的一個大事件。雖然這當然不是新聞,會看科技媒體的應該都有瀏覽過,但我想以自己的角度也深入去思考一輪,輸出跟大家分享。這7點的翻譯本身不是重點,真正的重點是Bezos想"改造"Amazon體質的那些思維。
Thumbnail
欲望是很神奇的東西,很久以前我一直想要一個App可以網羅所有英日文字典,手指一點就能在同一個畫面跳查好幾家字典。我心想英文和程式語言都是語言,乾脆自己下海寫一個App看看。過程歷經千辛萬苦,還是讓我寫出來了。想知道我怎麼做到的嗎?
即將到職滿一周年,平時每幾個月就會記錄一下期間內做了什麼、學了什麼,算是給自己的總回顧...
Thumbnail
自春季末開始求職以來,大約也經過了半年,期間陸續接觸了近十間軟體企業,拓展了不少眼界。依循著前人「取之於社群,回饋於社群」的精神,我也希望能為產業貢獻一己之力,以一個求職者的視角,分享我親身體驗的軟體企業面試現況。
Thumbnail
*合作聲明與警語: 本文係由國泰世華銀行邀稿。 證券服務係由國泰世華銀行辦理共同行銷證券經紀開戶業務,定期定額(股)服務由國泰綜合證券提供。   剛出社會的時候,很常在各種 Podcast 或 YouTube 甚至是在朋友間聊天,都會聽到各種市場動態、理財話題,像是:聯準會降息或是近期哪些科
Thumbnail
紀錄一下2020年以來做過的斜槓(不務正業)的工作有哪些,包含自創line貼圖、APP開發還有錄製podcast。比較慘的就是沒賺到啥錢,但也沒有什麼損失就是了。
Thumbnail
首先我接受了一些企業的面談邀約,包含才式、紅樓與麗臺,本文會記錄我在這三間公司面試的過程。
Thumbnail
首先我接受了一些企業的邀約,包含禾向、博訊、弘一與鯨躍,本文會記錄我在這四間公司面試的過程。
Thumbnail
煩惱不知道該用什麼數位筆記嗎? Heptabase 會是你最佳的選擇。Heptabase 在心智圖 、網絡、區塊間取得絕佳的平衡。簡樸直觀的設計讓你很專心的寫筆記,絕對是高效的知識工作者必備的工具之一。
從一開始的JavaScript,到後面HTML和CSS,雖之前有稍微碰過一點其他線上課程的內容,但AC系統性的教學,一個單元一個單元循序漸進的上課方式滿適合我的,有一種在打遊戲破關的感覺,非常享受。 已經報名學期二了,期望自己在學期二能夠維持學習進度,持續精進! 謝謝AC!
Thumbnail
如果有在接觸軟體開發產業,很常見的一個說法是非本科(資訊、工程背景)的工程師底子差,做出來的東西很糟糕之類的。然而,事實真的是這樣嗎?又或者說,我們能夠如何解決這樣的問題?
Thumbnail
關於Bezos的「API命令」,這可說是科技史中堪稱是教科書等級的一個大事件。雖然這當然不是新聞,會看科技媒體的應該都有瀏覽過,但我想以自己的角度也深入去思考一輪,輸出跟大家分享。這7點的翻譯本身不是重點,真正的重點是Bezos想"改造"Amazon體質的那些思維。
Thumbnail
欲望是很神奇的東西,很久以前我一直想要一個App可以網羅所有英日文字典,手指一點就能在同一個畫面跳查好幾家字典。我心想英文和程式語言都是語言,乾脆自己下海寫一個App看看。過程歷經千辛萬苦,還是讓我寫出來了。想知道我怎麼做到的嗎?
即將到職滿一周年,平時每幾個月就會記錄一下期間內做了什麼、學了什麼,算是給自己的總回顧...
Thumbnail
自春季末開始求職以來,大約也經過了半年,期間陸續接觸了近十間軟體企業,拓展了不少眼界。依循著前人「取之於社群,回饋於社群」的精神,我也希望能為產業貢獻一己之力,以一個求職者的視角,分享我親身體驗的軟體企業面試現況。