<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      SOLID原則、設計模式適用于Python語言嗎

      在閱讀 clean architecture的過程中,會發現作者經常提到recompile redeploy,這些術語看起來都跟靜態類型語言有關,比如Java、C++、C#。而在我經常使用的python語言中,是不存在這些概念的。于是,在閱讀的時候就會有一個疑惑,《clean architecture》中提到的各種原則,比如SOLID,是否對動態類型語言 -- 如python -- 同樣適用?

      SOLID是面向對象設計的指導原則,更具適用性的應該是各種設計模式,GOF經典的Design Patterns: Elements of Reusable Object-Oriented Software 也是用C++來舉例的,那么這些經典設計模式有多少是適用于動態語言如python的呢?本文記錄對這些問題淺薄的思考,如果有認知錯誤的地方,還請大家不吝指教。

      本文地址:http://www.rzrgm.cn/xybaby/p/11782293.html

      SOLID

      SOLID是模塊(module)設計的指導原則,有以下五個原則組成

      • SRP(Single responsibility principle):單一職責原則,一個module只有一個原因修改
      • OCP(Open/closed principle):開放-關閉原則,開放擴展,關閉修改
      • LSP(Liskov substitution principle):里氏替換原則,子類型必須能夠替換它們的基類型
      • ISP(Interface segregation principle):接口隔離原則,你所依賴的必須是真正使用到的
      • DIP(Dependency inversion principle):依賴倒置原則,依賴接口而不是實現(高層不需要知道底層的實現)

      ISP

      首先來看ISP,接口隔離原則,《clean architecture》的作者承認這是一個語言相關的原則

      This fact could lead you to conclude that the ISP is a language issue, rather than an architecture issue.

      為什么呢, ISP主要是為了解決“胖接口”導致的不必要的 recompilation and redeployment, 如下所示:

      Use1對op1的使用導致OPS的修改,導致User2 User3也要重新編譯。而在動態語言中是不存在重新編譯這樣的問題的:

      In dynamically typed languages like Ruby and Python, such declarations don’t exist in source code. Instead, they are inferred at runtime. Thus there are no source code dependencies to force recompilation and redeployment

      DIP

      DIP(依賴倒置原則)是SOLID的核心,OCP其實就依賴于DIP。也可以說,DIP是“clean architecture”的核心。

      “clean architecture”由兩部分組成:

      • well-isolated components
      • dependency rule

      什么是”Dependency rule"呢?讓低層的detail去依賴高層的policy。比如,業務邏輯(business rule)就相比數據存儲(database)出于更高層,雖然邏輯上是業務邏輯要使用數據庫,但為了可維護性、可擴展性,架構設計上得讓database去依賴business rule,如下所示

      從上圖可以看出,為了達到這個目的,在靜態語言中,會聲明一個接口,調用的雙方都依賴這個接口。如上圖中的database interface,讓business rule和database都去依賴這個接口,而這個database interface和business rule在一個component,這就實現了讓低層的database去依賴高層的business rule。

      在靜態類型語言(如Java、C++)中,其實就是利用運行時多態這個特性,使得可以在運行時 -- 而不是編譯時 -- 改變軟件的行為,當然為了達到這個目的,需要預先聲明一個虛基類 或者接口(Java Interface)。

      而在python中,本來就是運行的時候去求值,而且因為ducking type,所以無需事先聲明接口或者強迫繼承接口

      Dependency structures in these languages(dynamic typed languages) are much simpler because dependency inversion does not require either the declaration or the inheritance of interfaces.

      從靜態類型語言到動態類型語言,其實是省略了很多東西

      • 省略了虛函數,如template method模式
      • 省略了虛基類、接口,如DIP、strategy模式

      python中的依賴與依賴倒置

      在python中,怎么算依賴,怎么算依賴倒置?

      '''my.py'''
      import other
      class My(object):
          def f(self):
              other.act()
      

      這一段代碼中通過import讓module my依賴于module other,

      '''my.py'''
      class My(object):
          def __init__(self, actor):
              self._actor = actor
      
          def f(self):
              self._actor.act()
      

      那么在這里,my和other有依賴關系嗎?沒有的,這里壓根就沒有出現過other。由于動態類型加上ducking type,根本無需顯式的接口定義,只要遵循相關的協議(契約)即可。而這個契約,沒辦法通過代碼強行約束,調用者需要什么樣的接口,被調用者應該具備什么樣的行為,都只能通過文檔(或者單元測試)來描述。

      為了表達契約,上述代碼應該加上docstring

      '''my.py'''
      class My(object):
          def __init__(self, actor):
              '''Param: actor,該對象需要具備接收0個參數的act方法
              '''
              self._actor = actor
      
          def f(self):
              self._actor.act()
      

      python中大量使用類似的協議,如context management, iterator protocol。雖然很方便,同時也對程序員有更高要求,因為至少得有靠譜的docstring。如果需要強加約束,那是是可以考慮使用abc的。

      設計模式

      首先聲明的是,在本文中提到的設計模式,一般指Design Patterns: Elements of Reusable Object-Oriented Software 這本書中所描述的經典設計模式。

      很早之前看過一種說法,“++設計模式是對靜態語言缺陷的彌補”++,當時沒經思考就全盤接受了,竊認為這就是真理。最近才真正思考這個問題,發現這種說法存在偏見與不全面。

      首先拋出一個問題:設計模式是語言相關嗎(language-specific)?是某種類型的編程語言需要設計模式,而另外一些編程語言就不需要?或者說,不同的編程語言需要的設計模式是不一樣的?

      什么是設計模式呢,《Design Patterns》中描述為,針對軟件設計中某一類特定問題的簡單且優美的解決方案。

      Describes simple and elegant solutions to specific problems in object-oriented software design

      也就是說,設計模式是解決某類特定問題的套路,或者說方法論。套路是針對某個問題,經過理論或實踐驗證的、行之有效的方法與步驟。沒有方法論也能解決問題,可能就需要去大量的嘗試、試錯,得到一種解決辦法(大概率也不是最優解),這個求解的過程耗時且低效。因此可以說,方法論(模式)加速了問題求解的過程。

      比如,程序員每天都很大量的事情要做:要開會、要寫代碼、要處理bug、要自己充電。如何安排呢?可能自己思考這個問題就得焦頭爛額,但是已經有成熟的方法論 --艾森豪威爾矩陣-- 可供使用了啊。

      我們常說,站在巨人的肩膀上,套路、方法論就是巨人的肩膀。

      設計模式同樣如此。

      設計模式與動態語言

      《Design Patterns》這本書,寫于1994年,作者提到寫這本數的目標,就是將這些行之有效的經驗記錄下來。前面提到,設計模式是針對一類問題的解決方案,那么在介紹一種設計模式的時候,就一定會涉及到以下內容(包括但不限于):

      • 要解決的問題是什么
      • 解決方案是什么樣子的
      • 解決方案的缺陷與適用場景
      • 解決方案的詳細步驟
      • 針對同一個問題,有沒有其他解決方案,各自的優劣

      當然,首先得給這個模式取一個恰如其分的名字,命名的重要性不容質疑。至少保證程序員之間在溝通的時候所表達的是同一個問題,不管這個溝通是peer to peer,還是通過代碼。名字(術語、定義)也就減輕了溝通的成本。

      在《Design Patterns》寫成的兩年后,即1996年,Peter Norvig就做了一個分享 “Design Patterns in Dynamic Programming”, 指出由于動態語言存在更少的語言層面的限制,GOF中的大多數設計模式在Lisp或者Dylan有更簡單的實現,有的甚至簡單到根本無需注意

      16 of 23 patterns have qualitatively simpler implementation in Lisp or Dylan than in C++ for at least some uses of each pattern
      16 of 23 patterns are either invisible or simpler

      那么哪些模式變得“invisible”,哪些是“simpler”了呢?

      《Design Patterns》中講設計模式大致分為三類

      • Creational: ways and means of object instantiation
      • Structural: mutual composition of classes or objects (the Facade DP is Structural)
      • Behavioral: how classes or objects interactand distribute responsibilities among them

      由于在動態類型語言中,類(class, type)和方法(function)都是一等公民,因此Creational patterns在動態類型語言,如Python中就變得“invisible”。

      由于動態類型、ducking type,一些Creational patterns如“Observer”,“Visitor”就變得“simpler”。這里要強調的是,變得更簡單,并不意味這個這個模式就沒有存在的意義了,比如觀察者模式,或者訂閱-發布,代表了松耦合的設計原則,在各個層級的設計中都是需要的。

      對于這種體現更高原則、思想的設計模式,我們應該用模式去幫助思考和溝通,而不要拘泥于樣板代碼、特定語言實現。StackExchange上的這個排比句很恰當:

      - I might say that I have a visitor pattern, but in any language with first class functions it will be just a function taking a function. Instead of factory class I usually have just a factory function.
      - I might say I have an interface, but then it's just a couple of methods marked with comments, because there wouldn't be any other implementation (of course in python an interface is always just comments, because it's duck-typed). 
      - I still speak of the code as using the pattern, because it's a useful way to think about it, but don't actually type in all the stuff until I really need it.
      

      那么回到問題,設計模式是語言相關嗎(language-specific)?

      我的回答是,部分設計模式是語言相關的,部分設計模式不是語言相關的,具體到某一個特定的模式還可能是變化的。

      為什么呢,嚴謹一點,我們只能說設計模式是問題相關的 -- 是關乎某個問題的。核心在于,這個問題在什么情況下確實是一個問題。而且,隨著發展,一個老問題會消亡,新問題會出現。

      具體到編程語言,則應該關心的是一個問題是不是語言相關的。在靜態類型語言,如C++中,對象都有類型,類型決定了其行為,那么為了運行時多態,就得有一個虛基類,同時還要做到OCP,這就需要各式各樣的Creational Patterns。但到了動態類型語言,這個就不再是一個問題,因此就不再有與之對應的模式。

      references

      posted @ 2019-11-04 09:37  xybaby  閱讀(2271)  評論(3)    收藏  舉報
      主站蜘蛛池模板: 国内精品久久久久电影院| 亚洲另类无码一区二区三区| 中文字幕日本一区二区在线观看| 亚洲一区二区中文字幕| 国产精品午夜无码AV天美传媒| 少妇办公室好紧好爽再浪一点| 精品国产乱码久久久久久口爆网站| 国产强奷在线播放免费| 国产亚洲真人做受在线观看| 久久这里只有精品免费首页 | 东方av四虎在线观看| 青青草原国产精品啪啪视频| 人妻少妇偷人无码视频| 久久精品一本到99热免费| 国产中文字幕日韩精品| 骚虎视频在线观看| 欧美中文字幕在线看| 污污网站18禁在线永久免费观看| 亚洲第一香蕉视频啪啪爽| 日本高清视频网站www| 免费人成视频在线| 慈利县| 欧美高清一区三区在线专区| 久久亚洲精品国产精品婷婷| 亚洲一区二区三区啪啪| 国产精品综合一区二区三区| 中国少妇人妻xxxxx| 国产二区三区不卡免费| 久久亚洲精品国产精品尤物| 国产三级精品三级在线观看| 国产播放91色在线观看| 日韩一区二区三区亚洲一| 99热国产成人最新精品| 日韩黄色av一区二区三区| 亚洲午夜激情久久加勒比| 国产精品白浆在线观看免费 | 国产精品久久久久鬼色| 亚洲国产综合一区二区精品| 乱中年女人伦av三区| 激情综合色综合啪啪五月| 日韩激情无码av一区二区|