自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

高級程序員必須要會的五種編程范式

開發(fā) 前端
今天咱們來聊聊一個聽起來挺高大上的話題——編程范式。這詞兒聽起來可能有點唬人,但其實它就是描述編程時組織代碼的不同風格和方法。

今天咱們來聊聊一個聽起來挺高大上的話題——編程范式。這詞兒聽起來可能有點唬人,但其實它就是描述編程時組織代碼的不同風格和方法。

我會盡量用簡單的話給大家解釋清楚,每種范式到底是怎么一回事。這樣,當別人說起“面向?qū)ο蟆?、“函?shù)式”或者“聲明式”這些詞兒時,你就能心領(lǐng)神會了。

這篇文章主要是個簡單的理論介紹,當然啦,咱們也會看一些偽代碼和實際的代碼示例。

咱們開始吧!

什么是編程范式?

所謂的編程范式,其實就是我們組織程序或者編程語言的不同方式和風格。每種范式都有自己的一套結(jié)構(gòu)、特性,以及解決常見編程問題的方法和觀點。

為啥會有這么多不同的編程范式呢?這問題其實和為啥有這么多編程語言差不多。不同的范式適合解決不同類型的問題,所以針對不同項目使用不同的范式是有意義的。

隨著時間的推移,軟件和硬件的進步也推動了不同方法的發(fā)展。再加上我們?nèi)祟惖膭?chuàng)造力,我們總喜歡創(chuàng)造新東西,改進前人的成果,把工具調(diào)整成我們喜歡的樣子,或者看起來更高效的方式。

所以,今天我們在編寫和組織程序時,有很多選擇。

編程范式不是什么

要明確一點,編程范式不是編程語言,也不是工具。你不能用范式來“構(gòu)建”任何東西。它們更像是一套理念和指導原則,是很多人達成共識、遵循并不斷發(fā)展的東西。

編程語言并不總是和某個特定的范式綁定在一起。有些語言在設(shè)計時就考慮了特定的范式,并且提供了更多促進該范式編程的特性(比如Haskell和函數(shù)式編程)。

但也有很多“多范式”的語言,意味著你可以根據(jù)自己的需要,讓代碼適應不同的范式(比如JavaScript和Python)。

同時,不同的編程范式并不是互斥的,你完全可以在同一個項目中同時使用來自不同范式的實踐。

我為啥要關(guān)心這個?

簡單來說,就是為了增加你的知識面。

詳細點說,我覺得了解編程的多種方法很有趣。探索這些話題可以幫助你開闊思維,跳出你已經(jīng)熟悉的工具和框架。

而且,這些術(shù)語在編程界經(jīng)常被提及,所以有一個基本的了解,將有助于你更好地理解其他相關(guān)的主題。

好了,既然我們已經(jīng)介紹了編程范式是什么和不是什么,接下來就讓我們一起來看看最流行的幾種范式,了解它們的主要特點,并進行比較。

要記住,這個列表并不全面。還有一些其他的編程范式?jīng)]有在這里涵蓋到,但我會介紹最流行和最廣泛使用的幾種。

命令式編程

命令式編程由一系列詳細的指令組成,這些指令按給定的順序提供給計算機執(zhí)行。它之所以被稱為“命令式”,是因為作為程序員,我們會非常具體地告訴計算機必須做什么。

命令式編程關(guān)注的是描述程序是如何一步步運作的。

假如你想烤一個蛋糕,你的命令式程序可能看起來像這樣(我可不是個厲害的廚師,所以別太苛刻哦 ??):

1. 在一個碗里倒入面粉
2. 往同一個碗里打入幾個雞蛋
3. 往同一個碗里倒些牛奶
4. 混合這些食材
5. 將混合物倒入模具
6. 烤上35分鐘
7. 讓它冷卻下來

用實際的代碼示例來說,假設(shè)我們要過濾一個數(shù)字數(shù)組,只保留大于5的元素。我們的命令式代碼可能長這樣:

const nums = [1, 4, 3, 6, 7, 8, 9, 2];
const result = [];

for (let i = 0; i < nums.length; i++) {
   if (nums[i] > 5) result.push(nums[i]);
}

console.log(result); // 輸出:[6, 7, 8, 9]

我們告訴程序遍歷數(shù)組中的每個元素,將元素的值與5進行比較,如果元素大于5,就把它加入到新數(shù)組中。

我們的指令非常詳細具體,這就是命令式編程的核心。

過程式編程

過程式編程是命令式編程的一個延伸,它增加了函數(shù)(也稱為“過程”或“子程序”)的特性。

在過程式編程中,鼓勵用戶將程序執(zhí)行細分為函數(shù),作為提高模塊化和組織性的一種方式。

繼續(xù)我們的蛋糕例子,過程式編程可能是這樣的:

function pourIngredients() {
   // 在一個碗里倒入面粉
   // 往同一個碗里打入幾個雞蛋
   // 往同一個碗里倒些牛奶
}

function mixAndTransferToMold() {
   // 混合食材
   // 將混合物倒入模具
}

function cookAndLetChill() {
   // 烤上35分鐘
   // 讓它冷卻下來
}

pourIngredients();
mixAndTransferToMold();
cookAndLetChill();

你可以看到,通過實現(xiàn)函數(shù),我們可以直接看文件末尾的三個函數(shù)調(diào)用,對我們的程序做什么就有了一個清晰的了解。

這種簡化和抽象是過程式編程的好處之一。但在函數(shù)內(nèi)部,我們?nèi)匀皇褂玫氖敲钍酱a。

函數(shù)式編程

函數(shù)式編程將函數(shù)的概念提升到了一個新的層次。

在函數(shù)式編程中,函數(shù)被視為一級公民,這意味著它們可以被賦值給變量,作為參數(shù)傳遞,也可以作為其他函數(shù)的返回值。

另一個關(guān)鍵概念是純函數(shù)。一函數(shù)只依賴于它的輸入來生成結(jié)果。給定相同的輸入,它總是產(chǎn)生相同的結(jié)果。此外,它不會產(chǎn)生任何副作用(即不會對函數(shù)外部的環(huán)境產(chǎn)生任何改變)。

有了這些概念,函數(shù)式編程鼓勵我們用函數(shù)來編寫大部分程序(驚訝吧??)。它還主張代碼的模塊化和無副作用,這使得在代碼庫中更容易識別和分離責任,從而提高了代碼的可維護性。

回到數(shù)組過濾的例子,我們可以看到,在命令式范式中,我們可能會使用一個外部變量來存儲函數(shù)的結(jié)果,這可以被視為一個副作用。

const nums = [1, 4, 3, 6, 7, 8, 9, 2];
const result = []; // 外部變量

for (let i = 0; i < nums.length; i++) {
   if (nums[i] > 5) result.push(nums[i]);
}

console.log(result); // 輸出:[6, 7, 8, 9]

要將其轉(zhuǎn)換為函數(shù)式編程,我們可以這樣做:

const nums = [1, 4, 3, 6, 7, 8, 9, 2];

function filterNums() {
   const result = []; // 內(nèi)部變量

   for (let i = 0; i < nums.length; i++) {
       if (nums[i] > 5) result.push(nums[i]);
  }

   return result;
}

console.log(filterNums()); // 輸出:[6, 7, 8, 9]

代碼幾乎一樣,但我們把迭代包裝在了一個函數(shù)里,并且在函數(shù)內(nèi)部也存儲了結(jié)果數(shù)組。這樣,我們可以確保函數(shù)不會修改它作用域之外的任何東西。它只創(chuàng)建了一個變量來處理它自己的信息,一旦執(zhí)行完成,那個變量也就不存在了。

聲明式編程

聲明式編程的核心是隱藏復雜性,讓編程語言更接近人類的語言和思維方式。它與命令式編程正好相反,因為程序員不需要給出關(guān)于計算機應該如何執(zhí)行任務(wù)的指令,而是關(guān)于需要什么結(jié)果。

舉個例子,用數(shù)組過濾的故事來說,聲明式的方法可能是這樣的:

const nums = [1, 4, 3, 6, 7, 8, 9, 2];

console.log(nums.filter(num => num > 5)); // 輸出:[6, 7, 8, 9]

看到?jīng)],用filter函數(shù)時,我們并沒有明確告訴計算機要遍歷數(shù)組或者把值存儲到另一個數(shù)組里。我們只是說出了我們想要什么("filter")以及滿足的條件("num > 5")。

這樣的好處是,代碼更容易閱讀和理解,通常也更簡短。JavaScript中的filter、map、reduce和sort函數(shù)就是聲明式代碼的很好例子。

另一個好例子是現(xiàn)代的JS框架/庫,比如React。看看這段代碼:

<button onClick={() => console.log('你點擊了我!')}>點擊我</button>

這里我們有一個按鈕元素,帶有一個事件監(jiān)聽器,當按鈕被點擊時,會觸發(fā)console.log函數(shù)。

React使用的JSX語法將HTML和JS混合在一起,這讓編寫應用程序變得更加簡單快捷。但實際上,瀏覽器并不會直接讀取和執(zhí)行這樣的代碼。React代碼最終會被轉(zhuǎn)譯成常規(guī)的HTML和JS,這才是瀏覽器真正運行的東西。

JSX是聲明式的,因為它的目的是為開發(fā)者提供一個更友好、更高效的工作接口。

關(guān)于聲明式編程,一個重要的事情是,計算機在背后實際上是將這些信息作為命令式代碼來處理的。

以數(shù)組為例,計算機仍然會像在for循環(huán)中那樣遍歷數(shù)組,但作為程序員,我們不需要直接編寫這些代碼。聲明式編程所做的,就是將那些復雜性從程序員的直接視野中隱藏起來。

面向?qū)ο缶幊?/span>

面向?qū)ο缶幊蹋∣OP)是最流行的編程范式之一。

OOP的核心概念是將關(guān)注點分離到被編碼為對象的實體中。每個實體都會組合一組特定的信息(屬性)和可以由實體執(zhí)行的操作(方法)。

OOP大量使用類(這是從程序員設(shè)置的藍圖或樣板開始創(chuàng)建新對象的一種方式)。從類創(chuàng)建的對象稱為實例。

繼續(xù)我們的偽代碼烹飪示例,假設(shè)在我們的面包店中,我們有一個主廚(叫Frank)和一個助理廚師(叫Anthony),他們每個人在烘焙過程中都有特定的責任。如果我們使用OOP,我們的程序可能看起來像這樣:

// 創(chuàng)建對應每個實體的兩個類
class Cook {
   constructor(name) {
       this.name = name;
  }

   mixAndBake() {
       // 混合食材
       // 將混合物倒入模具
       // 烤35分鐘
  }
}

class AssistantCook {
   constructor(name) {
       this.name = name;
  }

   pourIngredients() {
       // 在一個碗里倒入面粉
       // 在同一個碗里打入幾個雞蛋
       // 在同一個碗里倒些牛奶
  }

   chillTheCake() {
       // 讓其冷卻下來
  }
}

// 從每個類實例化一個對象
const Frank = new Cook('Frank');
const Anthony = new AssistantCook('Anthony');

// 調(diào)用每個實例對應的方法
Anthony.pourIngredients();
Frank.mixAndBake();
Anthony.chillTheCake();

OOP的好處是,它通過明確的責任和關(guān)注點分離,促進了對程序的理解。

總結(jié)

正如我們所看到的,編程范式是我們面對編程問題的不同方式,以及組織我們代碼的方式。

命令式、過程式、函數(shù)式、聲明式和面向?qū)ο蠓妒绞墙裉熳钍軞g迎和廣泛使用的范式之一。了解它們的基礎(chǔ)知識對于一般知識和更好地理解編碼世界的其他主題都有好處。

責任編輯:華軒 來源: 科學隨想錄
相關(guān)推薦

2018-08-24 20:57:55

程序員編程語言Python

2018-03-28 13:32:43

程序員技能溝通

2017-12-06 10:43:51

程序員軟技能

2019-12-09 10:19:39

程序員技能開發(fā)者

2018-03-19 14:54:14

程序員朋友圈技術(shù)

2024-07-12 11:54:38

2015-04-30 09:07:15

2021-04-16 10:28:54

SQLJava代碼

2015-09-08 10:49:35

程序員編程經(jīng)驗

2009-07-28 10:18:03

程序員誤區(qū)

2017-11-09 07:58:07

程序員編程代碼

2016-12-08 10:53:46

程序員編程

2015-10-28 09:33:31

程序員崩潰編程語言

2022-05-23 07:56:19

語言DSLClojure

2020-06-22 13:37:18

程序員代碼紋身

2024-04-09 16:24:18

Promise開發(fā)

2023-11-01 08:01:48

數(shù)據(jù)結(jié)構(gòu)軟件工程

2015-07-08 09:39:53

程序員軟技能

2013-12-16 09:36:49

程序員編程語言

2018-09-27 16:35:01

程序員編程語言Python
點贊
收藏

51CTO技術(shù)棧公眾號