国产在线97色永久免费视频|亚洲日韩精品无码专区91|日日摸夜夜添狠狠添欧美|精品国产99国产精品

工程設(shè)計論——如何寫好工程代碼

   日期:2022-11-23     瀏覽:56     評論:0    
核心提示:一 內(nèi)容概述從抽象的工程設(shè)計論角度闡述了如何寫好一份代碼。闡述了設(shè)計模式和設(shè)計原則的底層原理。解釋了
 一  內(nèi)容概述
  1. 從抽象的工程設(shè)計論角度闡述了如何寫好一份代碼。闡述了設(shè)計模式和設(shè)計原則的底層原理。
  2. 解釋了設(shè)計模式與設(shè)計原則適用的場景及局限性。工程設(shè)計論是在有限設(shè)計能力下對被設(shè)計對象進行的認知和進行逆運算的過程。在不符合這一條件的領(lǐng)域,不應(yīng)當死扣設(shè)計模式與設(shè)計原則。在軟件領(lǐng)域,一個顯而易見的例子就是不要在極度追求性能的代碼中死扣設(shè)計模式與設(shè)計原則。
  3. 解釋了設(shè)計原則中的單一職責原則為何難以掌握和運用。
  4. 面向接口設(shè)計是軟件系統(tǒng)設(shè)計的最終形態(tài),對開發(fā)流程中先寫單例再開發(fā)的原因做了解釋。
    二  理論基礎(chǔ)
  1. 哲學(xué)基礎(chǔ):羅素《哲學(xué)問題》。
  2. 數(shù)學(xué)基礎(chǔ):矩陣理論,工程控制論。
  3. 工程基礎(chǔ):一定工程設(shè)計經(jīng)驗,如代碼開發(fā)等。
  4. 設(shè)計科學(xué)基礎(chǔ):謝友柏老師的《設(shè)計科學(xué)與設(shè)計競爭力》,Nam Suh的《公理設(shè)計》。

三  什么是設(shè)計——設(shè)計和計算與認知之間的聯(lián)系

 

一門科學(xué)的建立,應(yīng)當首先明確本學(xué)科的局限性,確定本學(xué)科最基本的問題與框架。明確的基本框架應(yīng)能夠迅速得到一門學(xué)科的基礎(chǔ)結(jié)論與研究方法;明確的基本問題可以用于檢驗上述的結(jié)論與方法。指出自然界中每一杯水中都有金元素并不能對金礦的發(fā)現(xiàn)起到什么促進作用。設(shè)計科學(xué)的現(xiàn)在的發(fā)展應(yīng)該做減法而不是做加法。對于設(shè)計所具備的特征,有很多描述。這些描述最基本的共同點是設(shè)計是需要達到一定的目標的(即需求)。其他特征并不是設(shè)計最基本的特征。例如最優(yōu)化設(shè)計中就沒有需求變更,logo設(shè)計中就沒有系統(tǒng)故障。

如果認同需求是設(shè)計的共同點,那么搞清楚需求是什么則是重要的。 大部分人都認為,在我們的實際工作中,需求是不明確的,不完整的。那我們不妨用辯證的思維來考慮這個問題的反面,什么是明確的,完整的需求?一份完整的需求,對于所有人而言都是清晰的,不會產(chǎn)生什么不一樣的理解。那么對于什么樣的產(chǎn)品能夠滿足相應(yīng)的需求,也應(yīng)該是清晰的。用集合論的話來說,一個集合被其外延所完全確定。換句話說,如果需求能夠被一個確定的驗收方式來定義,比如說單元測試,那么這份需求可以說是明確和完整的。

我們還需要更進一步地探討什么是驗收。以單元測試為例,我們用單元測試來輸出一個True或是輸出一個False;如果認為單元測試本身是一個函數(shù),那驗收就是要求被設(shè)計對象在該函數(shù)下的相必須為True。那么,如果我們的需求足夠簡單,會發(fā)生什么情況?比如說我們的需求是找到一個x,使其滿足x+1=0,我們一般稱這種問題為求解,或者是逆運算。可以看到,當我們對需求及其實現(xiàn)方式的認識完全清晰的時候,需求將退化成為一個函數(shù),設(shè)計將退化成為逆運算的過程。

設(shè)計的過程中,我們對于需求及實現(xiàn)方式的認識是不全面的,這是其與逆運算不同的核心點(而不是需求不明確或者是需求會發(fā)生變更)。例如化工產(chǎn)品的合成路線設(shè)計,例如高效排序算法的設(shè)計,都不存在需求本身不明確的問題。認知的不全面迫使我們需要在設(shè)計的過程中,一邊對需求及其實現(xiàn)方式進行認知,獲取更多的知識,一邊進行求逆運算,找到能夠滿足需求的實現(xiàn)方式。

四  工程設(shè)計的過程

在進行工程設(shè)計的過程中,對于認知和計算的交替流程,我們總結(jié)了一套行之有效的經(jīng)驗,即對需求的拆分和組合。

我們剛剛已經(jīng)說過,需求本質(zhì)上是要求一個對象,在某個函數(shù)下的像具備某些特征,這本質(zhì)上是一種約束。而“被設(shè)計對象由A,B兩個組件構(gòu)成,A具備123特征,B具備456特征”,這和需求的描述方式?jīng)]有什么不同,本質(zhì)上也是一種約束。也就是說,分拆本身也是對被設(shè)計對象的一種約束,只不過滿足分拆約束的對象并不一定滿足需求的約束。因此我們不妨把分拆的約束當作一種對被設(shè)計對象的弱約束。

因而工程設(shè)計可以被總結(jié)成為如下的流程:

  1. 根據(jù)對需求的相關(guān)研究,給出實現(xiàn)方式的弱約束,我們一般采用對系統(tǒng)拆分的方式來進行弱約束。在軟件領(lǐng)域,最常見的弱約束就是對組件劃分的約束,各個部件之間的依賴關(guān)系,接口的定義,數(shù)據(jù)交互方式之間的約束。(認知過程,我們一般稱之為需求拆解與架構(gòu)設(shè)計)
  2. 利用第一步的弱約束,來對需求中的強約束的實現(xiàn)方式進行具體的分析和求解。(逆運算過程,我們一般稱之為編碼)
我們剛剛已經(jīng)說明了,分拆本質(zhì)上也是一種約束。第二步中的求解結(jié)果,仍舊有可能是一種對子系統(tǒng)需求,此時就需要我們繼續(xù)進行更加細化的設(shè)計。

引入弱約束這個概念,是因為在我們對被設(shè)計對象一無所知的情況下,研究如何實現(xiàn)相應(yīng)的需求是相對困難的。那么我們不妨假設(shè)被設(shè)計對象具備某些性質(zhì)(這種假設(shè)往往也強依賴于個人經(jīng)驗),并將這些假設(shè)性質(zhì)(比如說接口)作為研究如何實現(xiàn)的一種工具和框架。

例如在代碼設(shè)計中,拆分為A,B兩個模塊并進行并行設(shè)計時,如果在A模塊的實現(xiàn)流程完全不知道B模塊的信息,那么將會對A模塊的設(shè)計產(chǎn)生巨大的阻礙(比如前端完全不知道后端的數(shù)據(jù)格式)。但是,B模塊的具體實現(xiàn)方式還未確定,此時A模塊也不可能對B模塊的信息由完整的了解,且并不是每一個B模塊的信息對于其他模塊都是有用的(比如后端選用的數(shù)據(jù)庫格式,后端部署的位置,后端的實現(xiàn)方式)。所以我們需要折中的對B模塊進行約束(比如規(guī)定接口),使得A模塊能夠獲得必要的相關(guān)信息。了解過認知論的同學(xué)也應(yīng)該知道,這種接口本身就是一種對B模塊的認知(參照羅素的感覺材料或是我在前序文章中所述的“關(guān)系”)。我認為這是依賴注入的底層邏輯,也是面向接口設(shè)計將成為軟件設(shè)計的最終形態(tài)的底層依據(jù)。

 

公式化地來描述上述流程,對于一個找到滿足的設(shè)計問題,我們將這個問題分為兩步:
  1. 將J(X)=0拆分成為
  2. 根據(jù)的性質(zhì),找到使得的的具體值,例如;并同時研究,找到的具體形式,例如。
在這個例子中,工程設(shè)計與科學(xué)研究后進行計算的最大區(qū)別即在于,第二步中的具體實現(xiàn)過程是并行的。各個組件的實現(xiàn)的并行在軟件工程中是常見的(前后端分別編碼,最后進行調(diào)試即是如此)。我們當然可以在完全研究清楚J(X)的性質(zhì)下,再去進行設(shè)計。限制我們不去這么做的條件,并非是這樣得到的產(chǎn)品效果一定不好,而是設(shè)計需要投入的工期與人力有限制。完全設(shè)計好前端之后,再去進行后端設(shè)計,當然是可以的,但是這種串行化的工作模式,顯而易見的會對工期造成負面影響。
為了使得這種拆分方式可行,獨立職責的原則就需要被引進以保證最后的組裝工作順利完成。在上一步中,我們的工作是并行的,意味著我們并不知道所需要取得的值是多少。如果我們最終研究得到

那我們顯然是找不到相應(yīng)的解的。這就需要我們保證f({X}),g({X}),m({X})之間的相互獨立。我們對拆分地獨立性及其負面影響進行進一步地探討:
  1. 強獨立:存在一個定義域為兩個自變量組X構(gòu)成的二元空間,值域為自變量組X的函數(shù)融合函數(shù)U;使得對于任意的
  2. 弱獨立:對于任意的
  3. 不獨立:存在
對于強獨立而言,只要組合函數(shù)J,及部分函數(shù)f,g的研究和求解是成功的,設(shè)計即是成功的。強獨立的意思是,如果我們分別找到兩個取值,使得部分函數(shù)f,g的值取到了我們想要的結(jié)果m,n;那我們可以根據(jù)找到一個綜合的解使得部分函數(shù)f,g同時取到我們想要的值。比如說對于:。那么對任意一個我們要求的f,g的取值,我們都可以將其用,來保證。

對于弱獨立而言,同時對組合函數(shù)J,及部分函數(shù)f,g進行研究,可能會帶來組合上的困難,但是不至于使得設(shè)計徹底失敗。比如說對于:。對于任意的m,n,我們都是能找到來滿足我們的需求的(注意這里一般是由研究組合函數(shù)J的同學(xué),來提出對部分函數(shù)f,g詳細取值要求m,n)。由于對函數(shù)g進行研究和設(shè)計的人,事先可能不知道,他們完全可能設(shè)計出來的方式。因此這種情況,需要后期的合作與調(diào)試,才能完成整個設(shè)計。

對于不獨立而言,同時對組合函數(shù)J,及部分函數(shù)f,g進行研究,可能會使得設(shè)計徹底失敗。比如說,。研究組合函數(shù)J的同學(xué)最終得到的答案可能是,這顯然是無解的。因此這個拆分可以認為是失敗的。

這一規(guī)則對應(yīng)于軟件領(lǐng)域中的單一職責原則,有人評論這一原則是較為難以運用和掌握的(“單一職責原則是最簡單但又最難運用的原則”)。事實確實如此,接下來我們將對這一點進行探討。

我們換一種看起來正確的模棱兩可的表述更方便我們發(fā)現(xiàn)問題在哪。這個陳述是:獨立的功能應(yīng)當由獨立的類來實現(xiàn)。那么,問題出現(xiàn)了。我們怎么去判斷兩個功能之間相互獨立?熟悉哲學(xué),并對哲學(xué)中對“Free”的討論有接觸的人會很快反應(yīng)過來,“Free”這個詞必然是建立于某種映射之上,單獨說A與B“Free”沒有任何意義。家庭教育和學(xué)校教育是否獨立?道德教育和智力教育是否獨立?從不同的角度會有不一樣的答案。從時間上,家庭教育和學(xué)校教育相互獨立;從評分標準上,道德教育和智力教育也相互獨立。如果把教育也作為一種設(shè)計,我們是應(yīng)該把教育劃分成為家庭教育和學(xué)校教育,還是劃分成為道德教育和智力教育?劃分的依據(jù)究竟應(yīng)該是什么?

顯而易見的事情是,我們所能夠接受的判斷功能之間的相互獨立的依據(jù),應(yīng)該是從其實現(xiàn)方式上相互獨立。那么上面那句話,就可以改寫成為:實現(xiàn)上獨立的功能應(yīng)當被獨立地實現(xiàn)。這有點像一句政治正確的廢話,其具體的運用強依賴于設(shè)計人員對于相關(guān)領(lǐng)域的事前經(jīng)驗與判斷。不具備相關(guān)領(lǐng)域的經(jīng)驗,進行功能劃分必然會出現(xiàn)一些搞笑的結(jié)果。這就是單一職責原則是最簡單,也最困難的原則的原因。

五  總結(jié)與局限

設(shè)計是在對需求的認知不完整的情況下,對被設(shè)計對象進行求解的一個過程。這就迫使我們需要一邊認識被設(shè)計對象,一邊進行求解。為了并行化地進行這一過程,也為了使得對被設(shè)計對象地認識有初步的研究工具和基礎(chǔ),我們總結(jié)出了一套利用分拆提供弱約束,并基于這種分拆,來并行進行不同組件之間的設(shè)計的流程。由于分拆只能提供關(guān)于被設(shè)計對象的較弱認識,因此依賴倒置和面向接口設(shè)計是必須的。為了使得并行化的設(shè)計最終可以被組裝,單一職責原則(獨立原則)是必須的。

可以看到,整個設(shè)計理論是必須基于對需求的認知不完整,且需要低成本(首要的是時間成本)地完成設(shè)計這一條件。對于設(shè)計周期比較長,認知較為充分的領(lǐng)域,設(shè)計理論并不適用。完全只用設(shè)計模式來衡量設(shè)計的好壞,也是不可取的。這方面的反例有很多,LeetCode上面的題目,恐怕沒有哪一個符合了設(shè)計模式,比如說找鏈表倒數(shù)第k個節(jié)點中的雙指針就是一個典型。對于人體而言,也并不遵循什么單一職責原則,甚至可以說耦合地不像,人在饑餓的時候,可以分解蛋白質(zhì)來供能;我們在飛機設(shè)計過程中,有考慮過在液壓油泄露時,拿燃油來充當液壓油么?一些經(jīng)典設(shè)計也并不遵循設(shè)計理論與原則,例如活塞環(huán)既能夠防止漏氣,又能夠降低摩擦磨損,這顯然也不是符合獨立公理的。

只有對設(shè)計科學(xué)的底層邏輯有著深入的研究,才能使得這門科學(xué)發(fā)揮其真正的作用。雖然本文盡可能地對這個領(lǐng)域進行了一些減法地操作,略去了一些不核心的要素,但是無論在理論上,還是例子上,都沒有能夠提供一個真正能夠被驗證成為正確或是錯誤的想法或是命題。本文甚至連錯誤都算不上,這無論如何都是讓人不滿意的。

六  附——利用分拆來設(shè)計系統(tǒng)的一個例子

很多設(shè)計領(lǐng)域的文章提出的例子,都是一些已有的設(shè)計;或是拿著根本沒有市場的需求來設(shè)計一款產(chǎn)品。這種先射箭后畫靶的行為并不能促進科學(xué)的發(fā)展。因此找一個大家都熟知的領(lǐng)域,提出解決起來較為有難度,但是需求明確的問題來作為探討的例子。很幸運的是,我的確解決了我自己提出的問題。

在機械領(lǐng)域,平面桿件機構(gòu)的設(shè)計是最基本的問題。例如對下圖中這種四桿機構(gòu),我們經(jīng)常會進行擺角的設(shè)計等工作。那么,我們能不用勻速的電機和平面桿件,使得平面桿件上的某一點有著指定的軌跡?例如用平面桿件畫一只兔子?

對于這個問題,我們梳理我們已經(jīng)知道的知識,來給出一些弱約束:
  1. 一個確定的平面桿組機構(gòu),其上任意一點的位置都是一個隨時間變化的周期函數(shù)。我們可以用復(fù)數(shù)域上的函數(shù)來進行表示,即:
  2. 由勻速電機帶動的桿件(主動件),其終點的軌跡是一個圓,且這個圓的運動規(guī)律與其他桿件無關(guān)。
  3. 不由勻速電機帶動的桿件(從動件)的軌跡,由主動件的運動軌跡和其與主動件的鏈接所決定。
那么,我們再由拆分給出另外的弱約束,以解決這一問題:
  1. 最終設(shè)計的平面桿組,由主動件和一些連接組構(gòu)成。這些連接組應(yīng)當具備兩個自由端點,且連接組上一點在運動中始終是這兩個自由端點的中點,即。
在這樣一個弱約束下,我們的問題就變?yōu)榱耍?/section>
  1. 如何通過一些圓周運動,及建立在其上的加法體系,擬合任意一個周期運動。
  2. 如何找到一個連接組,使得其具備上述條件。
問題一的答案由傅里葉變換給出:

問題二可以由如下桿組完成,轉(zhuǎn)動副2始終為轉(zhuǎn)動副1,3的中點:


最終的設(shè)計,我用了16個主動件,及16個連接組,共計80個桿件,得到的結(jié)果已經(jīng)在上圖中展示了。

誠實而言,我認為這個例子在說明弱約束和強約束,以及拆分對于工程設(shè)計的必要性方面,仍舊難以擺脫先射箭后畫靶的嫌疑。但是至少,我不認為我設(shè)計的機構(gòu),就是本問題的最優(yōu)解;我想本問題用以說明工程設(shè)計并不能得到最好的設(shè)計這一點,還是足夠的。
 
打賞
 
更多>同類資訊中心
0相關(guān)評論

推薦圖文
推薦資訊中心
點擊排行