日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

工程设计论——如何写好工程代码

發(fā)布時(shí)間:2024/8/23 编程问答 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 工程设计论——如何写好工程代码 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

簡(jiǎn)介:設(shè)計(jì)是在對(duì)需求的認(rèn)知不完整的情況下,對(duì)被設(shè)計(jì)對(duì)象進(jìn)行求解的一個(gè)過(guò)程。這就迫使我們需要一邊認(rèn)識(shí)被設(shè)計(jì)對(duì)象,一邊進(jìn)行求解。為了并行化地進(jìn)行這一過(guò)程,也為了使得對(duì)被設(shè)計(jì)對(duì)象地認(rèn)識(shí)有初步的研究工具和基礎(chǔ),我們總結(jié)出了一套利用分拆提供弱約束,并基于這種分拆,來(lái)并行進(jìn)行不同組件之間的設(shè)計(jì)的流程。

作者 | 任增
來(lái)源 | 阿里技術(shù)公眾號(hào)

一 內(nèi)容概述

  • 從抽象的工程設(shè)計(jì)論角度闡述了如何寫(xiě)好一份代碼。闡述了設(shè)計(jì)模式和設(shè)計(jì)原則的底層原理。
  • 解釋了設(shè)計(jì)模式與設(shè)計(jì)原則適用的場(chǎng)景及局限性。工程設(shè)計(jì)論是在有限設(shè)計(jì)能力下對(duì)被設(shè)計(jì)對(duì)象進(jìn)行的認(rèn)知和進(jìn)行逆運(yùn)算的過(guò)程。在不符合這一條件的領(lǐng)域,不應(yīng)當(dāng)死扣設(shè)計(jì)模式與設(shè)計(jì)原則。在軟件領(lǐng)域,一個(gè)顯而易見(jiàn)的例子就是不要在極度追求性能的代碼中死扣設(shè)計(jì)模式與設(shè)計(jì)原則。
  • 解釋了設(shè)計(jì)原則中的單一職責(zé)原則為何難以掌握和運(yùn)用。
  • 面向接口設(shè)計(jì)是軟件系統(tǒng)設(shè)計(jì)的最終形態(tài),對(duì)開(kāi)發(fā)流程中先寫(xiě)單例再開(kāi)發(fā)的原因做了解釋。
  • 二 理論基礎(chǔ)

  • 哲學(xué)基礎(chǔ):羅素《哲學(xué)問(wèn)題》。
  • 數(shù)學(xué)基礎(chǔ):矩陣?yán)碚?#xff0c;工程控制論。
  • 工程基礎(chǔ):一定工程設(shè)計(jì)經(jīng)驗(yàn),如代碼開(kāi)發(fā)等。
  • 設(shè)計(jì)科學(xué)基礎(chǔ):謝友柏老師的《設(shè)計(jì)科學(xué)與設(shè)計(jì)競(jìng)爭(zhēng)力》,Nam Suh的《公理設(shè)計(jì)》。
  • 三 什么是設(shè)計(jì)——設(shè)計(jì)和計(jì)算與認(rèn)知之間的聯(lián)系

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

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

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

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

    四 工程設(shè)計(jì)的過(guò)程

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

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

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

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

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

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

    在這個(gè)例子中,工程設(shè)計(jì)與科學(xué)研究后進(jìn)行計(jì)算的最大區(qū)別即在于,第二步中的具體實(shí)現(xiàn)過(guò)程是并行的。各個(gè)組件的實(shí)現(xiàn)的并行在軟件工程中是常見(jiàn)的(前后端分別編碼,最后進(jìn)行調(diào)試即是如此)。我們當(dāng)然可以在完全研究清楚J(X)的性質(zhì)下,再去進(jìn)行設(shè)計(jì)。限制我們不去這么做的條件,并非是這樣得到的產(chǎn)品效果一定不好,而是設(shè)計(jì)需要投入的工期與人力有限制。完全設(shè)計(jì)好前端之后,再去進(jìn)行后端設(shè)計(jì),當(dāng)然是可以的,但是這種串行化的工作模式,顯而易見(jiàn)的會(huì)對(duì)工期造成負(fù)面影響。

    為了使得這種拆分方式可行,獨(dú)立職責(zé)的原則就需要被引進(jìn)以保證最后的組裝工作順利完成。在上一步中,我們的工作是并行的,意味著我們并不知道f(X),g(X),m(X)所需要取得的值是多少。如果我們最終研究得到

    那我們顯然是找不到相應(yīng)的解的。這就需要我們保證f({X}),g({X}),m({X})之間的相互獨(dú)立。我們對(duì)拆分地獨(dú)立性及其負(fù)面影響進(jìn)行進(jìn)一步地探討:

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

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

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

    五 總結(jié)與局限

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

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

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

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

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

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

    對(duì)于這個(gè)問(wèn)題,我們梳理我們已經(jīng)知道的知識(shí),來(lái)給出一些弱約束:

    那么,我們?cè)儆刹鸱纸o出另外的弱約束,以解決這一問(wèn)題:

    在這樣一個(gè)弱約束下,我們的問(wèn)題就變?yōu)榱?#xff1a;

    如何通過(guò)一些圓周運(yùn)動(dòng),及建立在其上的加法體系,擬合任意一個(gè)周期運(yùn)動(dòng)。

  • 如何找到一個(gè)連接組,使得其具備上述條件。
  • 問(wèn)題一的答案由傅里葉變換給出:
  • 問(wèn)題二可以由如下桿組完成,轉(zhuǎn)動(dòng)副2始終為轉(zhuǎn)動(dòng)副1,3的中點(diǎn):

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

    誠(chéng)實(shí)而言,我認(rèn)為這個(gè)例子在說(shuō)明弱約束和強(qiáng)約束,以及拆分對(duì)于工程設(shè)計(jì)的必要性方面,仍舊難以擺脫先射箭后畫(huà)靶的嫌疑。但是至少,我不認(rèn)為我設(shè)計(jì)的機(jī)構(gòu),就是本問(wèn)題的最優(yōu)解;我想本問(wèn)題用以說(shuō)明工程設(shè)計(jì)并不能得到最好的設(shè)計(jì)這一點(diǎn),還是足夠的。

    原文鏈接

    本文為阿里云原創(chuàng)內(nèi)容,未經(jīng)允許不得轉(zhuǎn)載。?

    總結(jié)

    以上是生活随笔為你收集整理的工程设计论——如何写好工程代码的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。