<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          獨(dú)家 | Python中的SOLID原則(附鏈接)

          共 4916字,需瀏覽 10分鐘

           ·

          2021-09-12 19:29

          作者:Mattia Cinelli

          翻譯:朱啟軒

          校對:歐陽錦


          本文約3500字,建議閱讀15分鐘
          本文通過一些Python示例代碼介紹了可以提高代碼可靠性的SOLID編碼準(zhǔn)則。


          標(biāo)簽:數(shù)據(jù)結(jié)構(gòu),編程,數(shù)據(jù)科學(xué)

          SOLID原則是由Robert C. Martin提出的以首字母縮寫命名的編碼準(zhǔn)則,它代表了五種不同的編碼習(xí)慣。

          如果您遵循這些原則,您就可以通過完善代碼的結(jié)構(gòu)和邏輯來提高代碼的可靠度。

          Photo by ThisisEngineering RAEng on Unsplash

          以下是SOLID的五大原則:

          • The Single-Responsibility Principle (SRP)

            單一任務(wù)原則

          • The Open-Closed Principle (OCP)

            開閉原則

          • The Liskov Substitution Principle (LSP)

            Liskov替換原則

          • The Interface Segregation Principle (ISP)

            界面分離原則

          • The Dependency inversion Principle (DIP)

            從屬倒置原則


          這五個原則并沒有一個特定的先后順序(做這個,然后做那個,等等),他們是歷經(jīng)幾十年發(fā)展而成的最佳組合。為了方便記憶,他們被用一個縮略詞(SOLID)所概括。類似的方法在計(jì)算機(jī)中也有出現(xiàn)過,例如: DRY: Don 't Repeat Yourself;KISS: Keep It Small and Simple;每一個首字母背后都是人們智慧的結(jié)晶。順便提一下,這個縮寫詞是在這五項(xiàng)原則建立多年后才產(chǎn)生的。

          一般來說,SOLID原則是每個代碼開發(fā)人員的基本學(xué)習(xí)步驟,但通常它會被那些不把代碼質(zhì)量放在第一位的人所忽略。

          然而,作為一名數(shù)據(jù)科學(xué)家,我認(rèn)為遵循這些原則是有益的。具體地說,它提高了代碼的可測試性,減少了技術(shù)上的障礙和為了實(shí)現(xiàn)客戶/股東的新需求而修改代碼所需的時間。

          在下文里,我將探討這五個原則,并提供一些Python的示例。通常,SOLID原則應(yīng)用于面向?qū)ο蟮木幊糖榫爸校?Python的類),但我相信無論您的寫碼水平如何,他們都對您是有效的。我會在這里提供示例和解釋,面向的是“高級初學(xué)者”的級別。

          1) 單一任務(wù)原則(SRP)

          “一個類應(yīng)該有且只有一個可以被改變的理由”


          換言之,代碼的每個部分((通常是一個類,但也可以是一個函數(shù)))應(yīng)該有且只有一個職責(zé)。因此,應(yīng)該只能有一個理由來改變它。

          您經(jīng)常會看到一段代碼在處理整個進(jìn)程。即,在那些返回結(jié)果之前加載數(shù)據(jù)、修改數(shù)據(jù)并繪制數(shù)據(jù)圖的函數(shù)。

          舉一個簡單的例子,我們有一串?dāng)?shù)組L = [n1, n2,…,nx],然后我們將對這個數(shù)組進(jìn)行一些數(shù)學(xué)運(yùn)算。例如,計(jì)算平均值、中位數(shù)等。

          比較糟糕的方法是讓一個函數(shù)做所有的工作:


          為了使這個函數(shù)更符合SRP原則,我們應(yīng)該做的第一件事是將函數(shù)math_operations分解為只有單一功能的函數(shù)!這樣的話,這個函數(shù)的職責(zé)就不能再往下繼續(xù)去細(xì)分了。

          第二步是創(chuàng)建一個函數(shù)(或類),一般命名為“main”。然后通過這個函數(shù)一步一步地調(diào)用所有其他函數(shù)。


          現(xiàn)在,您就只有一個更改與“main”連接的函數(shù)的理由了。

          這樣做的結(jié)果是:

          1. 錯誤范圍縮小起來會更容易。進(jìn)程中的任何錯誤都更具有指向性,從而加速了調(diào)試進(jìn)程。
          2. 代碼的任何部分都可以在其他地方再次使用。
          3. 此外,經(jīng)常被忽視的一點(diǎn)是,這樣做使得函數(shù)測試起來更加容易。關(guān)于測試的附注:您應(yīng)該在實(shí)際編寫腳本之前就編寫好了測試。但是,為了創(chuàng)造一些好的結(jié)果并展示給利益相關(guān)者,這常常會被忽視。

          對于第一個示例來說,這已經(jīng)是一個很大的改進(jìn)了。但是,創(chuàng)建一個“main”函數(shù)和調(diào)用只有單一責(zé)任的函數(shù)并沒有實(shí)現(xiàn)SR的全部原則。

          事實(shí)上,我們的“main”有許多原因需要去改變。這個類實(shí)際上是很脆弱的,很難去維護(hù)。

          為了解決這個問題,讓我們介紹下一個原則:

          2) 開閉原則 (OCP


          “軟件實(shí)體 … 應(yīng)該對拓展升級開放,對調(diào)試修改封閉”


          也就是說:您不需要修改已經(jīng)編寫好的代碼以適應(yīng)新的需求,而只需添加您現(xiàn)在需要的東西。

          這并不是說,當(dāng)代碼的前提需要修改時,您不用更改代碼,而是說,如果您需要添加與現(xiàn)有函數(shù)類似的新函數(shù),您不應(yīng)當(dāng)更改代碼的其他部分。

          為了澄清這一點(diǎn),讓我們參考前面看到的示例。如果我們想添加新的功能,例如,計(jì)算中位數(shù),我們應(yīng)該創(chuàng)建一個新的函數(shù),并將其調(diào)用添加到“main”中。這將增加一個擴(kuò)展函數(shù),同時也修改了“main”。

          我們可以通過將我們編寫的所有函數(shù)轉(zhuǎn)換成一個類的子類的方法來解決這個問題。在本例中,我創(chuàng)建了一個名為“Operations”的抽象類和一個抽象方法“get_operation”。(抽象類這個知識點(diǎn)通常要求比較高。如果您不知道什么是抽象類,您可以先運(yùn)行以下代碼進(jìn)行嘗試)。

          現(xiàn)在,所有舊的函數(shù)和類都被__subclasses__()方法調(diào)用。它將找到所有從Operations繼承的類,并運(yùn)行存在于所有子類中的函數(shù)“Operations”。


          如果現(xiàn)在我們想要添加一個新的功能,例如:median,我們只需要添加一個從類“Operations”繼承的類“median”。新形成的子類將立即被__subclasses__()獲取,不需要對代碼的其他部分進(jìn)行修改。

          我們將會得到一個非常靈活的類,它所需的維護(hù)時間也會是最少的。

          3) Liskov 替換原則(LSP)


          “那些使用指針或者引用基類的函數(shù)必須要在不知情的情況下使用派生類的對象”


          也可以說,“派生類對于他們的基類來說必須要是可替換的才行”.

          簡單地說,如果子類重新定義了同樣在父類中出現(xiàn)的函數(shù),用戶不應(yīng)該注意到任何差異,它只是基類的一個替代品。

          例如,如果您正在使用一個函數(shù),而您的同事更改了基類,那您不應(yīng)該注意到任何差異。

          在所有的SOLID原則中,這是最難理解和解釋的。對于這個原則,沒有標(biāo)準(zhǔn)的“教科書式的”解決方案,而且很難提供一個“標(biāo)準(zhǔn)示例”來展示。

          我可以用最簡單的方式來概括這一原則:

          如果在子類中重新定義了基類中也存在的函數(shù),那么這兩個函數(shù)應(yīng)該具有相同的行為。但是,這并不意味著它們必須強(qiáng)制性等同,而是:給定相同輸入能得出相同類型的結(jié)果。

          在示例ocp.py中,“operation”方法出現(xiàn)在子類和基類中,終端用戶應(yīng)該期望從這兩個類中得到相同的行為。

          這一原則的結(jié)果是,我們將以一致的方式編寫代碼,只有終端用戶會需要去了解我們的代碼是如何工作的。

          附錄:

          (您可以跳到下一個原則)。

          LSP的一個結(jié)果是: 在子類中重新定義的新函數(shù)應(yīng)該是有效的,并且可能在父類中使用相同的函數(shù)時被調(diào)用。

          這不是我們所常見的情況,事實(shí)上,通常我們?nèi)祟悾眉险摰姆椒▉硭伎肌N覀兊念悤紫榷x概念,然后用子類去擴(kuò)展之前定義的類的概念及其不同行為。

          例如,超類“哺乳動物”的子類 “鴨嘴獸”就是一個例外,那就是這些哺乳動物會產(chǎn)卵。LSP原則告訴我們它將創(chuàng)建一個名為“give_birth”的函數(shù),這個函數(shù)將對子類Platypus和子類Dog有不同的行為。因此,我們應(yīng)該會有一個比哺乳類更抽象的基類來適應(yīng)這一點(diǎn)。

          如果這聽起來非常令人困惑,請不要擔(dān)心,LSP原則在這方面的應(yīng)用很少有被實(shí)現(xiàn),目前還停留在理論階段。

          4) 界面分離原則 (ISP


          “具有很多面向特定客戶的界面會比只有一個的通用的界面要好”


          在寫類的時候,我們一般都只考慮使用一個界面,所有的方法和屬性都“暴露”出來了,因此,所有用戶可以與之交互的東西都屬于這個類。

          在這種意義上,IS原則告訴我們,類其實(shí)有所需的界面(SRP)就行了,我們應(yīng)該避免那些無法工作或沒有理由成為該類一部分的方法。

          當(dāng)子類從它不需要的基類繼承方法時,就會出現(xiàn)這個問題。

          讓我們來看一個例子:


          對于這個例子,我們有一個抽象類 “Mammal”,它有兩個抽象方法:“walk”和“swim”。這兩個元素將屬于“Human”子類,而只有“swim”將屬于“Whale”子類。


          實(shí)際上,如果我們運(yùn)行這段代碼,我們會得到:



          子類whale仍然可以調(diào)用方法“walk”,但它不應(yīng)該這樣做,我們必須避免它。


          ISP建議的方法是創(chuàng)建更多面向特定用戶的界面,而不是一個通用的界面。因此,我們的代碼示例變成如下:



          現(xiàn)在,每個子類只繼承它需要的東西,避免了調(diào)用斷章取義(錯誤)的子方法。如果繼承了不需要的東西,可能會產(chǎn)生難以捕捉的錯誤。


          這一原則與其他原則緊密相連,具體來說,它告訴我們要保證子類的內(nèi)容整潔度,排除對子類沒有用處的元素。這樣做的最終目的是讓我們的類能夠保持整潔,并將錯誤最小化。


          5) 從屬倒置原則(DIP)


          “抽象類不應(yīng)該依賴于細(xì)節(jié)。細(xì)節(jié)應(yīng)該依賴于抽象類。高級模塊不應(yīng)該依賴于低級模塊。兩者都應(yīng)該依賴于抽象類”

          因此,抽象類(例如,上面看到的界面)不應(yīng)該依賴于低級方法,而應(yīng)該都依賴于第三個界面。


          為了更好地解釋這個概念,我傾向于認(rèn)為這是一種信息流。


          假設(shè)您有一個程序,它接收一組特定的信息(文件、格式等),然后您編寫了一個腳本來處理它。


          如果這些信息有變化會發(fā)生什么?


          你將不得不重寫你的腳本并調(diào)整新的格式。失去與舊文件的兼容性。


          然而,您可以通過創(chuàng)建第三個抽象類來解決這個問題,該抽象類將信息作為輸入并將其傳遞給其他抽象類。


          這基本上也是API的用途。



          這一原則的設(shè)計(jì)理念有趣在于,它與我們通常的做法相反。


          考慮到DIP原則,我們將從項(xiàng)目的尾部開始,我們的代碼獨(dú)立于所輸入的內(nèi)容,它不受更改的影響,并且不受我們的直接控制。


          我希望您能在您的代碼中運(yùn)用這些概念,我知道它們是為我準(zhǔn)備的。除此以外,我還提供了一些我用來理解這些原則的材料。


          R. C. Martin, “The Principles of OOD,” 2013. 

          http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod


          https://codingwithjohan.com/blog/solid-python-introduction

          “Clean Code in Python” by Mariano Anaya


          原文標(biāo)題:
          SOLID Coding in Python
          原文鏈接:
          https://towardsdatascience.com/solid-coding-in-python-1281392a6a94

          編輯:王菁
          校對:汪雨晴



          譯者簡介




          朱啟軒,康奈爾大學(xué)研究生在讀,專業(yè)領(lǐng)域是應(yīng)用統(tǒng)計(jì),方向是數(shù)據(jù)科學(xué)。本科畢業(yè)于加州大學(xué)洛杉磯分校。熱愛數(shù)據(jù)科學(xué),對處理數(shù)據(jù),分析數(shù)據(jù)有自己的獨(dú)特見解。對新知識充滿了渴望,目前正在學(xué)習(xí)自然語言處理和深度學(xué)習(xí)方面的知識,希望能認(rèn)識更多志同道合的人,一起努力,一起進(jìn)步。

          翻譯組招募信息

          工作內(nèi)容:需要一顆細(xì)致的心,將選取好的外文文章翻譯成流暢的中文。如果你是數(shù)據(jù)科學(xué)/統(tǒng)計(jì)學(xué)/計(jì)算機(jī)類的留學(xué)生,或在海外從事相關(guān)工作,或?qū)ψ约和庹Z水平有信心的朋友歡迎加入翻譯小組。

          你能得到:定期的翻譯培訓(xùn)提高志愿者的翻譯水平,提高對于數(shù)據(jù)科學(xué)前沿的認(rèn)知,海外的朋友可以和國內(nèi)技術(shù)應(yīng)用發(fā)展保持聯(lián)系,THU數(shù)據(jù)派產(chǎn)學(xué)研的背景為志愿者帶來好的發(fā)展機(jī)遇。

          其他福利:來自于名企的數(shù)據(jù)科學(xué)工作者,北大清華以及海外等名校學(xué)生他們都將成為你在翻譯小組的伙伴。


          點(diǎn)擊文末“閱讀原文”加入數(shù)據(jù)派團(tuán)隊(duì)~



          轉(zhuǎn)載須知

          如需轉(zhuǎn)載,請?jiān)陂_篇顯著位置注明作者和出處(轉(zhuǎn)自:數(shù)據(jù)派ID:DatapiTHU),并在文章結(jié)尾放置數(shù)據(jù)派醒目二維碼。有原創(chuàng)標(biāo)識文章,請發(fā)送【文章名稱-待授權(quán)公眾號名稱及ID】至聯(lián)系郵箱,申請白名單授權(quán)并按要求編輯。

          發(fā)布后請將鏈接反饋至聯(lián)系郵箱(見下方)。未經(jīng)許可的轉(zhuǎn)載以及改編者,我們將依法追究其法律責(zé)任。



          點(diǎn)擊“閱讀原文”擁抱組織



          瀏覽 101
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  黄色影视在线观看 | 最新亚洲黄色视频 | 蜜乳一区二区三区有限公司 | 亚洲在线无码不卡视频 百度一下 | 蜜乳网站|