<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                _設計軟件有兩種方法:一種是簡單到明顯沒有缺陷,另外一種復雜到缺陷不那么明顯。 --托尼.霍爾_ ##5.1.1 前言 在軟件工程這一學科和行業里,關于軟件工程的解說有很多。有人說開發是一門藝術;有人說開發是一種技藝;也有人說開發是一門哲學。但個人認同從實用主義和理性的角度去理解。 例如一個框架,我們之所以認為它好是因為我們發現這個框架遵循了編程規范、適當地使用了設計模式、巧妙地結合了設計原則、有著穩定的依賴、代碼復雜度低、并且有著很高代碼覆蓋率的單元測試等等。 也就是說,好的框架都是可以被解釋的。既然可以被解釋量化,也就可以學習、參考和借鑒。 ##5.1.2 共性和可變性分析 關于共性和可變性分析,在《設計模式解析》一書中有著非常到位的講解。 CVA是一種很容易的理念,按我的理解即: **抽離共性、隔離變化** 。有點類似易經里面的“變”與“不變”。 誠然,在過去的教育中(包括大學在內的),對于軟件開發都著重談論面向對象開發,即OOD,以致于很多人都對面向對象開發產生了很大的誤解。而這種誤解所帶來的實際情況就是: **我們都在進行面向對象開發,但卻是標準呆板的面向對象開發,缺少生氣,缺少活力** 。 很多人,都沒有把我們開發人員作為專業人士看待,甚至連我們自己都否認我們是專業的。所以很多時候當產品提出需求時,我們提供的開發周期往往會被外界以講價的方式削減。何以?為什么醫生給出的手術時間病人沒有討價呢?因為很簡單,在病人的眼里,醫生是專業的。 若我們也想達到專業的層次時,何以為?學習、思考和實踐,我認為至少這三者是必不可少的。 所以,當我們在對PhalApi進行設計時,我們進行了一次又一次地醞釀、嘗試、思考。我們在思考:這些功能是否真的會在實際項目中被使用?開發人員是否可能很好地進行擴展?此種決策是否便于單元測試、從思路上減少代碼異味?。。。 我們謹記敏捷開發,不過度設計。但我們也確實需要一種思想上的指導。正好,我們看到了 **共性和可變性的分析(commonality and variability analysis, CVA)** 。 ##5.1.3 CVA和三種視角、抽象類之間的關系 引用一下《設計模式解析》一書中的圖表: ![apic](http://webtools.qiniudn.com/20150411005257_04c1b193d2cdbb012cb3db54bbe44649) 在這種理念的指導下,我們會更愿意將接口開發過程的共性抽離統一起來,而可變性部分的則可以由開發人員根據不同的項目情況進行快速定制實現。 ##5.1.4 不穩定性與抽象度分布 除了常談及到的“低耦合、高內聚”外,在對代碼進行靜態分析和衡量其可維護度時,還有一個值得注意的值,即:不穩定的度量。 不穩定的度量可以根據以下公式計算獲得: ``` I = 離心耦合 / (離心耦合 + 向心耦合) ``` 因此從宏觀上,我們的代碼結構,從上層到下層,應該向著穩定的方向遞增,也就是說越底層越應穩定。對應 **_穩定依賴原則的規則(SDP),包之間的依賴應該朝著穩定的方向:不穩定的包應該依賴于更穩定的包。_** ![1233112](http://webtools.qiniudn.com/20150411005257_23af8d40e592df6f4a870873871d3a04) 又結合不穩定性與抽象分布圖,我們PhalApi框架的代碼 **應該大部分分布在上圖中的抽象穩定區以實現框架高層的建設、少部分分布在具體不穩定區以提供一些基礎的功能** 。 ##5.1.5 創建和使用分離 在框架的特性中,包括:可重用、IoC Container以及SOLID五條原則的運用等。這里就部分SOLID原則的運用簡單說明一下。 ###(1)S:單一職責原則 這是我們一直都堅持遵守的原則,因為,我們也堅持 **短而美** 的寫法, **致力于編寫優雅的代碼、編寫人容易理解的代碼** 。 ###(2)O:開放-封閉原則 我們首先希望的是在進行接口開發過程中,當需要新增一個接口時是開放的,對已有的響應調用流程是封閉的。即我們只需要實現新接口邏輯即可,不需要改動其他過程的調用。因此在OCP原則的指導下,我們通過結合工廠方法封裝了對接口的初始化和調用。 ###(3)D:依賴倒置原則 PhalApi框架,最大的特色莫過于 **它提供了一種如何快速進行接口開發的機制,但它不強制你使用不必要的功能,甚至它還鼓勵你通過它來嘗試研發自己的框架** 。更進一步,PhalApi引入了新穎明確的概念,一如服務。我們把客戶端調用的接口稱之為接口服務,把服務端用到的資源稱之為資源服務。對于后者,PhalApi提供了靈活的DI機制,以支持各項目定制化的開發。 ##5.1.6 PhalApi核心架構圖 ![PhalApi-20150208](http://webtools.qiniudn.com/20150411005257_3d974a8af4cde7bcafa4c4e227f71e97) 顯然,到目前為止,從核心架構圖所折射出PhalApi的結構和代碼是如此的 **簡單明了、統一規范**。至少我是這么認為的,也是一直這樣努力的。 從上圖的核心架構圖可以看出,中間紅色部分的DI處于匯點位置,提供各種資源服務的定位、創建、管理和提供。 而左上角的代碼示例則表達本系統框架運行的主流程: **創建一個接口實例,運行響應**。 右上解黃色部分則為多變的接口應用開發的代碼,這里特意羅列了兩組接口,意在表明可以在此框架下掛靠多套接口。 最下面是接口開發過程中所用到的各種基礎設施和技術,如日志、配置讀取、緩存、加密、請求和響應等。同樣,除各應用項目中形式多變的接口開發外,這塊的底層技術亦支撐不一而足的需求。因為,PhalApi只是作了共性的抽離,即提供一級抽象且穩定的接口或者抽象類,以約定規約視角中接口的函數簽名,不作過多的具體實現。同時以DI作為輔助,支持快速擴展。 ##5.1.7 PhalApi核心執行流程 和其他框架不同,除了有文檔對基本使用有說明外,我們還提供了我們框架核心的設計和思想,以便大家洞明其中的原理從而進一步優化擴展。 這里,扼要說明一下PhalApi框架中接口請求背后的核心執行流程。 ![PhalApi-接口處理主流程 - 0227](http://webtools.qiniudn.com/20150411005257_54efc4d7bcb670c547a884cce43ad5ac) 從上圖的時序圖中可以看出,在PhalApi中,一個接口的請求處理,只要分為兩個環節: **接口服務初始化** 和 **接口服務調用** 。 ###(1)接口服務初始化 在Web Service中,往往需要對服務進行注冊發布后,才能開放請求。這里免去這一層,但遵循 **創建和使用分離** 的原則,我們將接口服務的初始化進行了封裝,以便可以統一進行初始化、異常處理和一些權限ACL的控制 ,甚至接口訪問的統計等操作,更為重要的是接口開發人員可以進行無緒開發,而不需要過多知道如何合法創建接口服務。 在1.2. 步驟中,UML時序圖中的::generateService()表示對靜態函數的調用,即對應代碼: ```javascript PhalApi_ApiFactory::generateService(); ``` 隨后,可以看到(假設我們這次請求的服務為:?service=Demo.DoSth),我們創建了一個指定接口的實例(此接口類須繼承于PhalApi_Api基類),并以變量a返回實例。 如果請求的服務非法,則會以 **400非法請求** 返回給客戶端。而正確創建接口服務a后,則會進行接口的初始化,其中有接口參數規則的解析和注冊了過濾器服務后的檢測操作。 當這一系列的操作都成功執行后,我們將會得到一個接口服務實例a返回。 因此,在接口服務的創建過程中,我們沒有過多地限制,而是預留了很大的空間給到接口項目定制開發。 至此,接口服務的創建完成。 ###(2)接口服務調用 在完成復雜的創建工作后,客戶端(備注:這里指的是服務端開發的開發客戶端)只需要簡單調用需要進行的操作即可。 而這一塊,則需要接口項目具體開發實現,也是我們項目級的核心部分。 在獲取接口服務的背后,我們建議結合領域驅動設計的理念,對項目代碼進行這樣的層級劃分: + Api接口層:用于接收參數并響應接口的請求; + Domain領域層:用于處理復雜的領域業務邏輯,保證規則只出現一次; + Model數據源層:更廣義上的Model層,提供數據來源,不限于DB; 最后,是我們客戶端關心的返回格式。 默認情況下,我們都是以JSON格式返回的,但仍然可以輕松支持其他格式的返回,如JSONP、XML等。只需要簡單地開發實現,然后重新注冊即可。 至此,接口服務的調用完畢。 ##5.1.8 DI支持下的輕松擴展 當使用一個開源框架時,我們既喜歡其強大的一面,但矛盾的同時我們又害怕其中的復雜性,原因莫過于:學習成本高、出現問題時怕駕馭不了。 而在這里,在PhalApi這里,這一切都是這么簡單,簡單地又如此明了。 當需要進行資源服務的擴展時,我們可以: ###實現自己需要的服務 實現指定資源服務在規約視角約定的接口,假設我們需要用文件來當作新的緩存存儲。則需: ```javascript class MyCache_File implements PhalApi_Cache { public function set($key, $value, $expire = 600) { //... } public function get($key) { //... } public function delete($key) { //... } } ``` ###在入口重新注冊 當實現自己的功能后,只需要簡單地在入口文件重新注冊即可。如: ```javascript DI()->cache = new MyCache_File(); ``` 最后,另人興奮的是,原來全部的調用代碼都不需要改動,即可享受后期調整升級后的新功能!完全避免了曾經那種“牽一發而動全身”的痛苦。并且,定制開發出來的實現類,還可以跨越業務在其他項目中共用。 這不正是我們常常所說的代碼重用嗎?而如今,我們很優雅地做到了! 然而,我們在實際開發中收獲到的遠遠不是代碼重用這么簡單,而是一種更好的開發實踐。因為通過DI使得創建和使用分離,所以我們可以讓高級的開發同學實現服務功能的開發,然后再提供給普通的開發同學使用,新手亦然,因為對他們來說:會用就行。當然,對于高級的同學,還應該遵循開發的最佳實踐,堅持單元測試,以保證我們提供了可靠的接口(廣義上的接口,非HTTP請求的接口)給我們的“客戶端”使用。 若如此,我們的開發合作豈不是很更合理、更明朗、更愉快?哈哈,我想是的。 作為一個框架,我們應當以發散的方式去設計;但為了能為應用提供可用的功能,我們又應當以收斂的方式去實現。 如果我們提供的功能不足以滿足大部分主流的業務場景,那么我們至少需要提供可擴展的空間。 正是出于這樣的考慮,我們虔誠地引入了DI。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看