主頁 > 軟體設計 > 一文探尋學習DDD的意義

一文探尋學習DDD的意義

2023-02-25 08:00:14 軟體設計

序:

《阿甘正傳》中,阿甘開始了不停地跑步,一段時間后,后面就有了很多追隨者一起跑,他們為什么跑哪?
  • 阿甘:我也不知道,只是想跑而已,
  • 追隨者:感覺這樣做是有意義的,而且阿甘也還在前面領跑,

類似地,一開始我也不知道DDD是什么,但當發現大家都在提DDD、都在學DDD的時候,我也像跟跑者一樣不由自主地加入了前行:既然有大牛提出了DDD,既然那么多人趨之若鶩,那么肯定有可取的地方,
然而,有一天,阿甘停止了跑步,他不想跑了,追隨者遇到了一個問題:我們還要跑么?當我們在學習DDD的程序中,感覺學而不得的時候,可能也會問:我們還要學么?這的確引人深思,
本文基于作業經驗,嘗試談談對DDD的一些理解,希望能夠更好地探尋學習DDD的意義,

關注DDD的價值

無論做業務,還是做平臺、中臺,大家常常會被交錯復雜的業務邏輯、晦澀耦合的業務代碼搞得心力憔悴,我想,大家對DDD的追求,也是對輕松支撐業務發展的訴求,在探尋有沒有合適的理論可以改善現狀,畢竟,美好生活,共同向往,

現狀:分層支撐機制

我們選擇各種框架、進行各種組織設計,核心是為了提高生產效率,但如果業務邏輯都是 case by case 地進行實作、缺少復用,那么研發成本是非常高的、投入周期也會非常長,
為了增加復用、縮短業務的落地時間,就需要很多通用的能力、產品,在我們的交付程序中,主要有兩個層次:
  • 基礎能力:相對原子的能力是基礎(域)能力,這個可以較好地支持業務定制,由于比較基礎,表達的產品能力范圍也是很大的,但是,一個完善的產品需要串聯的基礎能力是非常多的,串聯的成本也是非常高的,

  • 平臺產品:基礎能力的通用性,意味著缺少對場景的理解,缺少了進一步提升生產效率的“基因”,所以在交付的時候,會基于一些高頻場景進行抽象,形成平臺的產品能力,爭取做到“拆箱即用”,業務基于“平臺產品”這層進行定制的時候,理解成本會大大減少,

圖片

分層支撐框架

 

腐化:業務邏輯滲透

這樣的層次,看上去很美好:在起步階段,由于缺少歷史包袱,的確可以提升一定的生產效率,這是能力本身的收益,但是,越往后,隨著業務接入的增多,業務之間開始互相影響,研發的阻力也越來越大,
研發效能降低的重要原因在于:更多的時候,我們還是按照“業務能跑起來,怎么快怎么來“的邏輯去做相關作業,遇水搭橋,遇山開洞,然后直達目的地,進行資訊的傳達、資料庫欄位的操作,
這樣的程序,違背了我們”希望通過業務場景,豐富平臺能力,同時保證內核干凈“的初衷,能力應該是基于相對多的用例、相對完善的思考進行抽象,是橫向統一看,有更深刻的理解,但是垂直的交付,讓我們更加縱向地處理問題,往往只是“窺探”了鏈路,在交付時長和業務節點的限制下,很難想得更加全面、深刻,難以做出更通用的設計,

抵御:平臺框架守衛

那么,為什么關注DDD?如果說DDD直擊了軟體復雜度的核心——“問題域”,那可能還是比較抽象,具體來說,因為這的確符合我們追求的價值觀【提升長期的生產效率】
細分領域,培養專業的人、事:因為DDD的核心是要求讓各個領域做好理解和封裝,把一個業務需求拆解、安放在各自合理的地方,通過這樣的分解與沉淀,保證了領域的輸入,能夠得到長期可持續的發展,形成競爭力,
機制保障,不依賴易變的事物:DDD其實在總結很多通用的技巧和經驗,能夠讓這樣的實施更具有確定性,無論是聚合根對領域物體的管控能力、限界背景關系的互動策略、領域內核的抽象地位...等等,一旦選擇尊奉,確定下來,就能夠落在代碼結構、組織關系、團隊檔案中,形成共識,不會因為人員等因素的變化而劇烈波動,
對DDD的關注,可以類比于我們對“工匠精神”的關注,對DDD的重視,也是我們對業務理解的重視,貼近業務,更要理解業務,不僅要理解業務,更需要理解大多數的業務,這樣的追求,讓我們往上看了一個層次,回歸了最本質的問題:我們要解決什么問題?如何能夠解決得更好?

 

 

學習DDD的困難

不知道大家是否有這樣困惑:DDD的學習程序好像是”大海撈針“的程序,即使能夠撈到點東西,使用起來,還是會有種“東施效顰”的感覺,并不是很自然,為什么學習DDD那么困難呢?

 

感受:不得其門

論語中的下面這個場景,和我們的困惑是比較相似的:
叔孫武叔語大夫于朝曰:“子貢賢于仲尼,” 子服景伯以告子貢,子貢曰:“譬之宮墻,賜之墻也及肩,窺見室家之好;夫子之墻數仞,不得其門而入,不見宗廟之美、百官之富,得其門者或寡矣,夫子之云不亦宜乎!”

正如要感受到孔子達到的境界,自己的學問也需要有一定的積累,我們要感受到DDD的力量,自己本身就要成長到一定程度(如:經歷了一些成功或者失敗的設計,有自己的經驗或者教訓),才能形成共鳴和認同,

作業中,的確很少看到DDD的最佳實踐,在復雜的業務面前,誰也沒有勇氣說,哪個軟體結構是理想的設計:
  • 因為這不是一個確定性的問題分解,你的設計會被放在顯微鏡下研究,總能找到各種反例,
  • 而且,我們深知,最佳的實踐,一定是做得足夠的“軟”,對擴展留有設計,能夠隨著業務發展而迭代,不是一個靜態的結果,
因此,打開學習的大門不是幾個案例就能一蹴而就的,需要結合我們自己的作業,慢慢累積、體會,

困難:模式發散

我們有一種困惑,到底怎么樣算是DDD:
  • 實踐的個例,難以信服:當我們看到”DDD實踐“的時候,可能會發問:這也算DDD?不就是一個正常的服務端框架與方案,也無法涵蓋其它的場景或者部門系統,

  • 抽象的理論,覺得空洞:當我們看到”抽象的DDD定義與策略“的時候,可能會發問:這也算DDD?不就是一些軟體設計的共識,然后強加了一些名詞定義,有些策略與我們手上的系統也并不匹配,
無論往抽象看,還是往具體實作看,都很難找到令人信服的理論與實踐(能夠有確定性的落地能力),因為這不像23個設計模式那樣,可以通過N個模版就能涵蓋大多數的模式,
為什么不能產生特定的模式呢?可以結合下圖進一步來看:
  • 抽象理論:如同抽象的介面一樣,"DDD理解"最上面的學習主要是理論定義,比如:聚合根、值物件、資源庫、核心域、支撐域等各種定義,這些是易于理解掌握的,
  • 通用實踐:如同相對具體的抽象類一樣,"DDD理解"中間層次是一些通用原則和技巧,比如:背景關系的映射策略、架構的選擇等,這些因素是確定的,但需要自主進行取舍與選擇,并且需要與時俱進,增量的部分需要你自己學習補充,
  • 具體實踐:如同具體的類實體一樣,"DDD理解"中下面層次是一系列的具體實踐,結合各自的業務場景,進行了不同因素的設計、取舍與補充,因為涉及的選項較多,造成最終的選擇結果往往是發散的,令人感覺“千人千面”,
兩者不同的地方是:
  • “代碼抽象層次”中層次關系是比較明確的,且有約束,

  • “領域驅動理解層次”中無法提供明確的約束,都是多個策略的取舍、一些關鍵的建議,

因此,由于問題的抽象層次較高,各種策略的不確定性較高,很難在DDD中產生像”23個設計模式“那樣精煉的模式,一定要有的話,也是一系列的模式,比較發散,

圖片

DDD理解層次的類比
因此,我們漸漸明白:DDD面向的是軟體的“軟”,涵蓋方方面面,DDD的深入理解,需要“千錘百煉”后,才能明白那些深入簡出的建議,才能體會那句“師傅領進門,修行靠個人”的真言,才能感受到“眾里尋他千百度,那人卻在燈火闌珊處”的美妙瞬間,

基于設計原則看DDD

雖然DDD本身的實踐可能千人千面,但是一些核心主題的思考應該是聚焦的,這些高頻主題的理解,能讓我們更好地進行設計,討論的性價比也是較高的,接下來,會基于“6大設計原則”(solid 原則)為引子,去看看DDD中的一些關鍵理解,

 

單一職責原則:領域劃分

單一職責是說:一個類應該只有一個發生變化的原因,職責的單一,可以更好地內聚,減少耦合,方便演化,
DDD里面的領域劃分可以類比思考,對領域的劃分,無論是按領域物體,還是按照功能模塊,還是按照服務等劃分,其實都想盡量保證領域的正交,能夠獨立演化和發展,
圖片

Single Responsibility Principle:單一職責原則

領域怎么切分比較合適?剛進入業務平臺的時候,了解到領域切分是按“一個或多個物體物件”的邊界來切分,這的確比較合理,因為領域的核心職責就是對領域物體進行管理,但這是果,還是因?在切分的時候,是因為我們有了對領域的判斷,所以某些物體被分在一起比較合適;還是因為某些物體有明顯邊界,所以可以形成一個領域?就比如下面的圖:
  • 可以整體作為1個部分,

  • 可以按豎著的正、負切分2個部分:上面1個(紅),下面2個(黃、綠),

  • 可以按橫軸的正、負切分2個部分:左邊1個(黃),右邊2個(紅、綠),

  • 可以切分成3個部分(紅、黃、綠),

圖片

聚類的例子
這的確引入深思,切分比較容易的時候,往往是因為已經有了行業的標準(如:電商系統有訂單、支付、物流、庫存等領域是比較合理的),那行業的標準來自哪里?是來自于演化:
  • 開始的時候,可能只是一個大交易,比如:支付開始的時候只是買賣雙方自己協議,也不需要建模,
  • 后面支付發展了,也就獨立出來一個域,原來不需要專人維護,后面會漸漸拉出一個團隊來承接相關研發,

所以,領域的演化和劃分,很類似“啟發式演算法”(一個基于直觀或經驗構造的演算法,在可接受的花費下給出待解決組合優化問題每一個實體的一個可行解):
  • 初始化:按照的經驗初步的劃分,也可以是行業標準(沒有行業標準的時候,就只能靠經驗了),
  • 花費評價:生產、交付程序的人力成本度量,關注理解成本、開發效率、系統穩定性、運維成本等因素,
  • 更優解:在業務發展程序中,計算花費評價,分析影響評價的“好因素”、“壞因素”,進行進一步調整,
往往到最后,我們會發現:
  • 調整的內容:其實是匹配生產關系,

  • 調整的原則:追求職責的內聚,精細化分工,

  • 不斷調整的原因:業務在發展,內聚的標準需也要與時俱進,

此外,從關聯的角度看,往往我們看組織架構,就能看到領域的邊界,核心原因還是組織架構也是要適應生產關系,follow更優解的結構,是相輔相成的,也就能互相窺探,

 

開閉原則:物體行為

開閉原則是說:軟體中的物件(類、模塊、函式等)應該對于擴展是開放的,但是對于修改是封閉的,也就是說,對擴展區塊是要有設計的,擴展的部分不應該影響穩定邏輯,
在DDD中,物體的行為,在保證對外封閉的情況下,也是需要考慮擴展能力的,

圖片

Open Closed Principle:開閉原則

在剛開始學習DDD的時候,我們可能會強行把一些邏輯放到物體中,進行控制和收斂,但后面隨著業務的變化,會發現在物體中承擔行為邏輯很難受:
  • 影響較大:很難有勇氣去頻繁地修改一個核心類,
  • 過于集中:隨著方法和邏輯的增多,物體越來越臃腫,
  • 場景較多:很多邏輯并不是正交的,不是 if 這樣 else 那樣的,充滿著交集與疊加,
拋棄 POJO 的get、set,走向物體的豐富行為,讓我們撰寫代碼更加困難了么?其實,我們的煩惱來自于,太關注物體行為的收口,忽略了擴展的設計:
  • 原來 get set 寫法很舒服的本質在于,很多的擴展被放在了業務腳本中,業務腳本雖然千瘡百孔,但是是在應用層,遠離核心邏輯,底層模型、通用組件等基礎邏輯還是比較干凈的,

  • 應用DDD的時候,把一些行為下沉到領域層之后,也是要考慮擴展的,如果只關注收口,不關注擴展,那的確是“畫地為牢”、“撿了芝麻,丟了西瓜”,
但是,要突破這一個困境,能夠在物體行為中設計擴展,其實要有這樣的認同:要往上看一個層次,就是物體行為的表達,不一定只有一個類完成,可以通過策略模式等方式的路由,由一個模塊中的一些類進行完成,只要對外有封裝和管控其實就可以了,
突破一個類的限制,走向更多的類的協作設計,也是我們進階的方向,

 

里氏替換原則:資源庫

里氏代換原則是說:任何基類可以出現的地方,子類一定可以出現,講究的是合理的抽象和復用,引人深思的一個例子是:正方形是特殊的長方形,正方形如果作為長方形的子類,那么當設定長度的時候就會出現沖突,長方形的長和寬可以獨立設定,正方形的長和寬是有約束的,使用繼承的關系就比較別扭,
在DDD中,關于可替代性,想聊一聊資源庫,

圖片

Liskov Substitution Principle:里氏替換原則

【資源庫的替代性需求】
在原來的分層的架構中,資料庫等存盤能力作為一種底層基礎設施,是被視為穩定的下層服務的,但在實際的交付程序中,往往要遇到不同場景:
  • 本地部署:線下零售交易為了服務穩定性,期望可以具備本地保存資料的能力,
  • 云上產品:售賣給外部企業的交易產品,成本的要求也不盡相同,期望在云上采購不同的存盤服務,
這些場景,讓大家逐漸深信:當面向更廣闊的市場,基礎設施也是充滿著不確定性,需要具備可替換的能力,
【存盤實作間的復用策略】
在具體實作的程序中,并不是每個領域都會獨立部署,有些領域因為組織、性能的因素會一起部署,往往這些領域的代碼也是在一個專案模塊中的,出于橫向效率的考慮,會設計統一的存盤框架,
不同設施的存盤能力不同,但整個存盤流程又是類似的(協議轉換,存盤陳述句生成、執行與事務,回傳結果),這樣在不同存盤能力的程序復用方式上需要進行取舍(資料庫、Tair等是分開抽象還是統一抽象):
  • 如果“大一統”為主,那么針對關系型存盤、KV存盤等不同存盤進行抽象的時候,就會和“長方形與正方形的問題”一樣猶豫:

  • 收益:如果你長期維護,了解里面的特殊性,的確是可以省略一些主體代碼,提高開發效率,

  • 代價:但大多數人要做擴展的時候,會感到很多不解,有很多本不需要的適配,充滿迷惑,
  • 如果以組合為主,那么可以通過多套模版,更好地進行自主選擇,這樣分而治之,減少了大家的理解成本,也能獨立演化,更能適合存盤的能力特性,但是需要沉淀多套理解,往往也缺少人力支持,

我想,“基于不同的存盤能力,設計不同的模版框架” 應該是首選,大一統的抽象,開始時,人力成本可能低一點,但因為抽象層次較高,在理解與維護上將是一個“人力成本黑洞”,隨著時間的推移,會降低整體收益,長期看是得不償失的,反之,不同的模版復用,最終可以獲得更好的整體收益,

迪米特法則:領域協作

迪米特法則,又稱最小知識原則,是說:一個軟體物體應當盡可能少的與其他物體發生相互作用,應該和一些“關鍵類”進行溝通,
DDD里面,領域間的協作,也需要相關的規劃和設計,如果對領域之間的相互呼叫不做管理,那么鏈路關系會膨脹到難以理解的地步,

圖片

Law of Demeter:迪米特法則

設計模式中,無論是中介者模式,還是外觀模式,都希望通過集中管理,讓多對多的復雜關系,簡化為多對一、一對多這樣易于理解的結構,類似的,在領域協作與對外交付的程序中,往往可以增加一個協調層,去串聯各個域的互動,這樣即可以降低各域的協作成本,也可以降低外部的理解成本,有更好的研發體驗,
協調層該如何產生?好比上課:雖然老師可以教,但是老師不在時,可以指定學生代理上課,學生雖然可以干,但教學技巧并不熟練,自己本身還有學習的職責,角色也很尷尬,下面將討論一下協調層和域的角色關系,
【域能否成為協調層】
比較值得討論的是交易里面“交易域”、“訂單域”這樣的概念:
  • “交易域”看上去是負責整個交易程序,可以協調各個域,邏輯上比較合適成為協調者,但是主要還是在管理訂單,其它賦予的協調能力,這部分并沒有領域物體,
  • “訂單域”看上去只是負責訂單本身的服務,不太關心其他域,但是因為訂單合約上有著所有合約資訊(無論是直接還是間接持有),這意味著,“訂單域”本身就有協調的潛力,只是職責看上去不夠單一而已,

沒有物體,為什么會有“交易域”一說,本人是這么理解的:在交易流程等可以強管控的情況下,把交易的API服務當做域服務(如:下單),“交易域”在邏輯上是有邊界、可以成立的,但本質還是在管理訂單,靠訂單域成為了域,同時想沉淀協調能力,
【協調層能否成為域】
那么,如果訂單的模型的管理不給交易管理呢,就是本人一直想的問題:如果沒有自己的資料庫物體,只有記憶體模型,純粹靠對下游業務活動理解、資料流轉的理解,能否成為一個域?
答案大概率可能是不行的:
  • 邏輯上個人是認可純靠理解作為一個域,畢竟知識本身也是一種資產,

  • 但實際上,沒有載體,就做不了特別多事情,包括狀態記錄,資料服務等,只能輔助,沒有核心競爭力,難以生存下來,
協調者的角色,想要成為一個比較公認的“域”,必定要自己持有資料模型,或者,借助基礎域的一些資料模型,并享有管理的權限,
【協調層的名稱】
無論是域想承擔協調者的角色,還是協調者想發展成一個域,其實都不太符合職責單一的邏輯,但是這樣“兼職”的現象卻時常發生,核心還是開發人員角色的重疊,
既然協調層不太適合從域中選出,也不太適合成為一個域,那么介于業務活動、各個域能力之間的協調部分,應該稱之為什么呢?目前看“商業能力”、“解決方案”這樣的詞匯都是比較合適的,

 

介面隔離原則:業務活動

介面隔離原則是說:客戶端不應該依賴它不需要的介面,一個類對另一個類的依賴應該建立在最小的介面上,
DDD里面除了領域建設的學習,也需要關注應用層如何更好地承接業務請求,并研究業務邏輯分割的依據,

圖片

Interface Segregation Principle:介面隔離原則
【沒有規矩,難成方圓】
之前在業務部門做業務的時候,并沒有業務活動、流程等相關概念,往往是基于業務需求寫業務腳本,經驗的多少會影響代碼的優雅,但除了經驗,大家并沒有比較好的結構框架、原則,去承接應用層的各種業務邏輯,因此也充滿疑惑:
  • 對外服務介面應該如何切分?

  • 類似服務之間是否可以共用流程?

  • 業務執行程序如何進一步結構化切分?

  • ......
沒有規范的結果是,往往各有各的看法,誰都想立一套結構,誰也不服誰起的一套,各有各的代碼區域,
【平臺的穩定框架】
現在作業中,因為在平臺,平臺思考和治理的時間也比較久了,也有比較穩定的共識,整體的設計,在業務入口和業務入口之間、業務入口和穩定邏輯之間,預留了空間和擴展能力去承接場景化的邏輯,結構也比較確定:
  • 入口按業務活動切分:服務入口按照業務活動擴展,核心理解并關注用例,什么角色要干什么事情,
  • 流程獨立承接與編排:業務活動在到達復用層(如:領域服務、外部服務、業務擴展)前保持獨立,各自編排,
  • 借助流程檔案編排執行程序:將執行程序切分為執行節點,節點的切分可以以“功能點”、”涉及的域“、“涉及的物體“等為依據,節點間的共同能力下沉到基礎能力中,
  • ......

【反復review形成共識】
分而治之,縮小大家的關注點,更好地切分協作,這樣的確很容易理解并接受,但是要保證合理的切分,還是要有統一的共識和原則,
往往一致的形成,不是先一致共識,再切分,而是初步溝通后就嘗試切分,再review達成一致,在曲折中前進,如果大家的看法、沖突較大,那么這個共識達成的程序就相對較慢,好在,這種切分也不是時常發生,也就大需求、大重構的時候,此時,預留的研討時間、開發資源也是充足的,

依賴倒置原則:六邊形架構

依賴倒置原則是說:程式要依賴于抽象介面,不要依賴于具體實作,
DDD里面提到的六邊形架構,也是進一步提升了抽象內核的地位,把領域建設作為架構的核心目標,

圖片

Dependence Inversion Principle:依賴倒置原則
以領域為中心,其實是一個比較重要的轉變:
  • 原來以分層架構為主:講究按層次去看,盡量將能力下層,進行更多工具復用,積累的是通用組件,
  • 現在以領域為中心:講究按抽象層次去看,盡量將理解融入到領域核心,進行更多“理解”復用,積累的是業務知識,
這樣的轉變,讓我們有意識地將“領域理解”作為核心,形成行業競爭力,把“知識”作為資產進行售賣,
為了保證領域內核的抽象,需要定義好領域內核的邊界,有兩類介面:
  • 對上游提供的能力:通過介面宣告,說明能承擔的職責,在領域內部進行實作支撐,
  • 對下游的能力依賴:外部服務、業務擴展定制、存盤服務都可以作為下游服務看待,通過介面宣告服務依賴,
可以看到,領域內核與外部之間通過介面進行解耦,對于更基礎的服務,會被視為和業務入口一樣的外部埠,屬于應用層,比如,存盤服務:
  • 原來更多的是基礎能力:資料框架 + DO,不需要理解轉換,轉換在上游完成,DO 也會作為核心模型被上游使用,在采用遵循模型策略的時候,上游完全使用 DO 作為核心物件進行流轉,
  • 現在可以理解為“業務組件“:需要實作領域的存盤介面,承擔協議轉換,將領域物件轉換為資料存盤物件DO,DO也不會被領域直接理解,需要轉換為領域物件再往外透,被領域內核定義了表現,
這樣的架構,奠定了領域理解的抽象核心地位,讓研發同學更加注重對業務問題的思考,建設更多“有血有肉”、“貼近業務核心問題”的軟體,不僅僅是“基礎骨架”,讓我們更加走近客戶的價值,是應對軟體復雜性程序中,大家比較認可的方向,

總結

對DDD的追求,來自我們渴望優雅地解決各種業務問題,希望有一套框架可以引導我們去分解問題,得到穩定、高效的生產效率,
但是這好比對“永動機”的追求,是一個難以有肯定答案的程序,能夠解決軟體復雜性的方案,必定是結合相關場景并且不斷演化的,單純追求DDD是得不到“銀彈”的,
不過正如對“永動機”的研究,能讓我們關注能量的轉換程序,可以引導我們制造出更加高效的能源機器,對DDD的研究與追捧,能夠讓我們更加關注對業務的深刻理解,可以引領我們寫出更加易于擴展的代碼實作,
我想,正是“業務的不斷發展”、“軟體的復雜性”的存在,才讓編程充滿了挑戰,才讓大家對框架的研究充滿熱情,這何嘗不是一個美妙的事情那~
作者|閔大為

本文來自博客園,作者:古道輕風,轉載請注明原文鏈接:https://www.cnblogs.com/88223100/p/One-article-explores-the-significance-of-learning-DDD.html

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/545001.html

標籤:架構設計

上一篇:Java面向物件進階第一天

下一篇:我用ChatGPT做直播技術選型,卷死了同事

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more