天天看點

Python 中的面向接口程式設計

Python 中的面向接口程式設計

<code>”面向接口程式設計“</code>寫 <code>Java</code> 的朋友耳朵已經可以聽出幹繭了吧,當然這個思想在 <code>Java</code> 中非常重要,甚至幾乎所有的程式設計語言都需要,畢竟程式具有良好的擴充性、維護性誰都不能拒絕。

最近無意間看到了我剛開始寫 <code>Python</code> 時的部分代碼,當時實作的需求有個很明顯的特點:

不同對象具有公共的行為能力,但具體每個對象的實作方式又各不相同。

說人話就是商戶需要接入平台,接入的步驟相同,但具體實作不同。

作為一個”資深“ <code>Javaer</code>,需求還沒看完我就洋洋灑灑的把各個實作類寫好了:

Python 中的面向接口程式設計

當然最終也順利實作需求,甚至把組裡一個沒寫過 <code>Java</code> 的大哥唬的一愣一愣的,直呼牛逼。

Python 中的面向接口程式設計

不過事後也給我吐槽:

你這設計是不錯,但是感覺好複雜,跟代碼時要找到真正的業務邏輯(實作類)得繞幾圈。

截止目前 <code>Python</code> 寫多了,我總算是能總結他的感受:就是不夠 <code>Pythonic</code>。

雖說 <code>Python</code> 沒有類似 <code>Java</code> 這樣的 <code>Interface</code> 特性,但作為面向對象的進階語言也是支援繼承的;

在這裡我們也可以利用繼承的特性來實作面向接口程式設計:

代碼非常簡單,在 <code>Python</code> 中也沒有類似于 <code>Java</code> 中的 <code>extends</code> 關鍵字,隻需要在類聲明末尾用括号包含基類即可。

這樣在每個子類中就能單獨實作業務邏輯,友善擴充和維護。

由于 <code>Python</code> 作為一個動态類型語言,無法做到 <code>Java</code> 那樣在編譯期間校驗一個類是否完全實作了某個接口的所有方法。

為此 <code>Python</code> 提供了解決辦法,那就是 <code>abc(Abstract Base Classes)</code> ,當我們将基類用 <code>abc</code> 聲明時就能近似做到:

一旦有類沒有實作方法時,運作期間便會抛出異常:

雖然無法做到在運作之前(畢竟不需要編譯)進行校驗,但有總比沒有好。

以上兩種方式看似已經畢竟優雅的實作面向接口程式設計了,但實際上也不夠 <code>Pythonic</code>。

在繼續之前我們先聊聊<code>接口</code>的本質到底是什麼?

在 <code>Java</code> 這類靜态語言中面向接口程式設計是比較麻煩的,也就是我們常說的子類向父類轉型,是以需要編寫額外的代碼。

帶來的好處也是顯而易見,隻需要父類便可運作。

但我們也不必過于執着于接口,它本身隻是一個協定、規範,并不特指 <code>Java</code> 中的 <code>Interface</code>,甚至有些語言壓根沒有這個關鍵字。

動态語言的特性也不需要強制校驗是否實作了方法。

在 <code>Python</code> 中我們可以利用鴨子類型來優雅的實作面向接口程式設計。

在這之前先了解下鴨子類型,借用維基百科的說法:

“當看到一隻鳥走起來像鴨子、遊泳起來像鴨子、叫起來也像鴨子,那麼這隻鳥就可以被稱為鴨子。”

我用大白話翻譯下就是:

即便兩個完全不想幹的類,如果他們都實作了相同的方法,那就可以把他們當做同一類型的類來使用。

舉個簡單例子:

這裡的 <code>order</code> 和 <code>user</code> 本身完全沒有關系,隻是他們都有相同方法,又得益于動态語言沒法校驗類型的特點,是以完全可以在運作的時候認為他們是同一種類型。

是以基于鴨子類型,之前的代碼我們可以稍作簡化:

因為在鴨子類型中我們在意的是它的行為,而不是他們的類型;是以完全可以不用繼承便可以實作面向接口程式設計。

我覺得平時沒有接觸過動态類型語言的朋友,在了解完這些之後會發現新大陸,就像是 <code>Python</code> 老手第一次使用 <code>Java</code> 時;雖然覺得文法啰嗦,但也會羨慕它的類型檢查、參數驗證這類特點。

動靜語言之争這裡不做讨論了,各有各的好,鞋好不好穿隻有自己知道。

随便提一下其實不止動态語言具備鴨子類型,有些靜态語言也能玩這個騷操作,感興趣下次再介紹。

作者:

crossoverJie

出處:

https://crossoverjie.top

Python 中的面向接口程式設計

歡迎關注部落客公衆号與我交流。

本文版權歸作者所有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出,

如有問題, 可郵件(crossoverJie#gmail.com)咨詢。