1. 程式人生 > >Python設計模式面向物件程式設計

Python設計模式面向物件程式設計

前言

  本篇文章是基於極客時間王爭的《設計模式之美》做的總結和自己的理解。
  說到面向物件程式設計,作為一個合格的Pythoner,可以說信手拈來。畢竟在Python裡“萬物都是物件”嘛,如果別人說你根本不會面向物件程式設計,或者根本不理解面向物件,那可能會得到你的謾罵,那說到底,你真的懂面向物件嗎?試著回答下面幾個問題:

  • 面向物件程式設計的定義是?Python為什麼是面向物件程式語言?Python裡萬物都是物件具體的表現形式是什麼?
  • 面向物件的特性是哪四點?在Python裡這四點都具備嗎?具體是如何實現的?

提示:如果上述的問題回答起來很清晰、很清楚,那本篇文章就可以跳過了,如果感覺思路不清晰,那本篇文章多多少少都會給你程式碼幫助 !

設計模式簡介

  在聊面向物件程式設計之前,先看下設計模式,設計模式主要由程式設計正規化、設計原則、設計模式構成,具體如下圖:

  圖裡概念相對較多,但初步掌握,只要有個大概的印象即可。

談談面向物件

面向物件歷史

  什麼是面向物件,從歷史說起,我們知道Python正式釋出是1991年,Linux正式釋出也是1991年,Java正式釋出是1995年,Go正式釋出是2009年,而面向物件的概念歷史發展是:1960年的simula首次提出類和物件的概念,隨後70年代的程式語言Smalltalk首次用到面向物件概念,可見面向物件概念提出之早,而隨著軟體的發展,後續大多數語言都成了面嚮物件語言,那面向過程的語言有嗎?有的,C語言就是典型的面向過程語言。
  有興趣的可以去讀一讀維基百科,瞭解下這些語言的發展歷史。

  • 面向物件-維基百科
  • Python-維基百科
  • Java-維基百科
  • Linux-維基百科
  • Go-維基百科
面向物件概念

  面向物件,即object-oriented,在其下又細分為面向物件分析、面向物件設計、面向物件程式設計,即OOA(Analysis)、OOD(Design)、OOP(programming)。
  如果看了維基百科,可能還是很模糊,通過下圖知道關鍵字:程式設計正規化、包含屬性和方法、是類的例項、程式的基本單元、目的是提高軟體的擴充套件性和靈活性。那一句話就是:面向物件是一種程式設計正規化,以類和物件為基本單元,通過封裝、抽象、多型、繼承這四大特性(不是強要求)來實現程式碼設計,目的是為了提高軟體的可維護性、可擴充套件性、可複用性。當然上述是我的個人一句話,並不專業,但意思到位即可。


  那Python為啥是面向物件程式語言,很明顯,它提供了類和物件這一特性來組織程式碼,同時也具備了四大特性,那自然是。但不具備四大特性一定不是面向物件程式語言嗎?很明顯這不具備參考定義,隨著軟體的發展,很多語言脫離了四大特性,比如Java雖然支援繼承,但不具備多繼承;比如Go直接放棄了繼承這樣的特性,而Java和Go又多出了interface這一介面特性,在Python裡則不支援,但它們三者都是面向物件程式語言。

萬物皆物件

  我們經常聊Python萬物皆物件,這句話怎麼理解?很簡單,在Python裡我們要構造一個類物件的時候,都是以繼承object為前提的,所以判斷“萬物”是不是物件,只要判斷它是不是歸屬於物件即可,這裡的萬物概念很廣,比較常見的以:數字、字串、布林、函式為例,那結果如下:

  為啥都是物件型別呢?我們再以其中的布林值為例,通過dir發現其內有大量的屬性和方法(如下圖),那這些方法總不能憑空而來,所以都是繼承來的,接下來就比較清晰了,當我們用變數指代數字、字串等等時,實際上是構造了一個又一個的物件,這些物件具備的魔法方法使其能支援一系列操作,比如__lt__使其具備了比較小於的能力,比如__eq__使其具備了等等於判斷的能力。

面向物件的特性

  關於四大特性:封裝、抽象、繼承、多型,可以看下圖的總結:

  Python天然支援四大特性,以前老是對封裝和抽象比較模糊,理解為二者都是封裝抽象公共程式碼,然後提供給其他方法呼叫,這樣的理解就很片面了,因為二者的意義相差很大。封裝是用於隱藏實現和保護資料,比如Python裡我們常在類裡定義私有型別來供外部程式呼叫(如下圖),這裡可以看到a相當於Java的public關鍵字,是允許任意呼叫;而_a則是Pythoner里約定俗成的私有方法,如果呼叫pycharm這種ide會用波浪線提示使用者說是不合法的引用;如果是__a,則相當於Java的private,如果外部呼叫ide會直接標黃表示錯誤。

  結果如下:

  至於抽象,廣義上的理解即是抽取公共程式碼,對外暴露相應的方法;狹義上的理解就是介面這樣的概念,在介面類裡僅包含要暴露的方法,而不透露具體實現,也就是“基於介面而非實現程式設計”。很可惜,在Python裡並不提供介面這一特性,如果你對介面比較模糊的話,可以搜尋下介面類 interface,相信會了解到不少資訊。但Python裡可以通過duck-typing和抽象基類來額外實現抽象,關於這個後續的文章再詳細介紹了。
  另外繼承和多型則是基本語法了,這裡也不細說。

總結

  本篇文章就到這了,雖然說得都是基礎,但相信如果你看完了還是會有一些收