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

為什么您的代碼需要抽象層?

譯文
開源
抽象是編寫設(shè)計(jì)良好的軟件最重要的方面之一。了解這個(gè)基本概念將為您提供可遵循的系統(tǒng)和清晰的思維模型,以了解如何創(chuàng)建好的抽象。

[[434567]]

【51CTO.com快譯】抽象是編寫設(shè)計(jì)良好的軟件最重要的方面之一。

了解這個(gè)基本概念將為您提供可遵循的系統(tǒng)和清晰的思維模型,以了解如何創(chuàng)建好的抽象。

好的抽象降低了復(fù)雜性,并允許開發(fā)人員更輕松地更改代碼并減少錯(cuò)誤。但是創(chuàng)建抽象并非易事。那么您究竟如何做到這一點(diǎn),需要采取哪些步驟?

什么是抽象?

談?wù)摯a中的抽象層之前,不妨簡要地談?wù)劤橄笫鞘裁础?/p>

抽象可以定義為通過以下方式簡化實(shí)體的過程:

1. 省略不重要的細(xì)節(jié)。

2. 暴露接口。

所有抽象在這方面都大同小異。

自動駕駛汽車是抽象的實(shí)際例子。在這種情況下,離合器是抽象的,駕駛員可以更輕松地?fù)Q檔。

抽象也有不足。比如說,雖然駕駛員可以更輕松地?fù)Q檔,但現(xiàn)在對汽車的控制也較少,因此為賽車駕駛員抽象離合器可能是壞主意。

作者John Ousterhout在《軟件設(shè)計(jì)理念》一書中談到了抽象可能出錯(cuò)的兩種方式:

1. 包含不重要的細(xì)節(jié):由于包含不重要的細(xì)節(jié),抽象變得過于復(fù)雜,導(dǎo)致開發(fā)人員的認(rèn)知負(fù)擔(dān)加大。

2. 省略重要細(xì)節(jié):Ousterhout將這種抽象稱為“虛假抽象”,因?yàn)椴榭闯橄蟮拈_發(fā)人員不會擁有他們需要的所有信息。

所以,好的抽象需要兼顧和權(quán)衡。

代碼中的抽象

我們已知道了抽象,但它如何應(yīng)用于代碼?

所有代碼可以歸類為策略或細(xì)節(jié)。

  • 策略:這些是實(shí)體和業(yè)務(wù)邏輯。
  • 細(xì)節(jié):這是策略的實(shí)現(xiàn)。細(xì)節(jié)執(zhí)行策略。

假設(shè)您有一個(gè) User 實(shí)體。用戶有某個(gè)接口以及某個(gè)業(yè)務(wù)邏輯。這個(gè)User實(shí)體還有組,您被指派編寫獲取所有用戶組的代碼。

在這里,策略是用戶本身,因?yàn)樗且粋€(gè)實(shí)體,但它也是getUserGroups函數(shù),因?yàn)樗桥c該實(shí)體相關(guān)的業(yè)務(wù)邏輯。

它如何實(shí)現(xiàn)、使用哪個(gè)數(shù)據(jù)庫、使用哪個(gè)ORM(對象關(guān)系映射)、使用哪些庫、如何編寫代碼以及所有不同的實(shí)現(xiàn),這些都是代碼的細(xì)節(jié)部分。

在您的代碼中,您希望在隱藏細(xì)節(jié)的同時(shí)暴露策略。策略和細(xì)節(jié)之間的這種分離讓您可以切換和輕松重構(gòu)實(shí)現(xiàn)。

如果您的策略和細(xì)節(jié)是耦合的,就很難重構(gòu),因?yàn)樗鼈兓旌显谝黄?,更改會從一個(gè)傳播到另一個(gè)。

在設(shè)計(jì)良好的系統(tǒng)中,策略和細(xì)節(jié)之間的分離是關(guān)鍵。

那么這如何應(yīng)用于抽象層呢?

抽象層

抽象層暴露了接口,并隱藏了它背后的實(shí)現(xiàn)細(xì)節(jié)。

抽象層的目的是創(chuàng)建抽象。層里面的方法和屬性應(yīng)該是暴露的接口,而這些方法里面的實(shí)現(xiàn)是細(xì)節(jié)層中的一切。

創(chuàng)建抽象層主要有三個(gè)好處:

1. 集中​​:通過在一層中創(chuàng)建抽象,與其相關(guān)的所有內(nèi)容都是集中的,因此可以在一處進(jìn)行任何更改。集中與“不要重復(fù)自己”(DRY)原則有關(guān),這很容易被誤解。

DRY不僅涉及代碼的重復(fù),還涉及知識的重復(fù)。有時(shí),兩個(gè)不同的實(shí)體可以復(fù)制相同的代碼,因?yàn)檫@可以實(shí)現(xiàn)分離,允許這些實(shí)體將來分別演進(jìn)。

2. 簡化:通過創(chuàng)建抽象層,您可以暴露特定的功能并隱藏實(shí)現(xiàn)細(xì)節(jié)。現(xiàn)在代碼可以直接與您的接口交互,避免處理不相關(guān)的實(shí)現(xiàn)細(xì)節(jié)。這提高了代碼的可讀性,減輕了閱讀代碼的開發(fā)人員的認(rèn)知負(fù)擔(dān)。為何?

因?yàn)椴呗圆蝗缂?xì)節(jié)復(fù)雜,所以與其交互更直接。

3. 測試:抽象層非常適合測試,因?yàn)槟梢园鸭?xì)節(jié)換成另一組細(xì)節(jié),這有助于隔離正在測試的區(qū)域,并正確創(chuàng)建測試替代(test doubles)。

測試代​​碼時(shí),開發(fā)人員需要測試特定的功能,同時(shí)為某些功能創(chuàng)建測試替代,以避免調(diào)用真正的數(shù)據(jù)庫之類的對象。策略和細(xì)節(jié)糾纏在一起時(shí),過度使用測試替代很常見,這使得覆蓋率更低,測試的用處也大大降低。

為數(shù)據(jù)庫實(shí)現(xiàn)對象創(chuàng)建抽象層時(shí),開發(fā)人員可以替換該層,確保在測試其余功能時(shí)僅替換數(shù)據(jù)庫響應(yīng)。

創(chuàng)建抽象層的示例

假設(shè)您為組創(chuàng)建API編寫代碼:

  1. function createUserGroup(group, userId) { 
  2.         logger.info('Creating group for user ${userId}'
  3.         db.startTransaction(); 
  4.         const isValidGroup = validateGroup(group); 
  5.         if (!isValidGroup) throw new Error('Invalid group'); 
  6.         db.addDoc('groups'group
  7.         dc.addDoc('quotas/groups', 1) 
  8.         . 
  9.         . 
  10.         . 
  11.     } 

可從上述例子看出,該函數(shù)邏輯與策略和細(xì)節(jié)混合在一起。它處理很多不同的功能,并不使用任何抽象層。

這是使用抽象層的代碼:

  1. class GroupsService { 
  2.     GROUPS_COLLECTION = 'groups'
  3.     createGroup() { 
  4.         db.startTransaction(); 
  5.          
  6.         const isValid = this.validateGroup(); 
  7.         if (!isValid) throw new Error('Invalid group'
  8.          
  9.         db.addDoc(GROUPS_COLLECTION, group
  10.         quotasService.setQuota('/groups', 1); 
  11.          
  12.         db.finishTransaction(); 
  13.     } 
  14.      
  15.     validateGroup() 
  16.      
  17.     deleteGroup(); 
  18. class QuotasService { 
  19.     setQuota(collection: string, value: any) { 
  20.         dc.addDoc(`quotas/${collection}`, value) 
  21.     } 
  22. function createUserGroup(group, userId) { 
  23.     logger.info(`Creating group for user ${userId}`) 
  24.     groupsService.createGroup(); 
  25.      
  26.     return { 
  27.         status: 200, 
  28.         message: 'Group created successfully' 
  29.     } 

第二個(gè)實(shí)現(xiàn)有諸多好處:

1. 更容易理解,因?yàn)閷?shí)現(xiàn)細(xì)節(jié)是抽象的,您在閱讀的是與策略交互的代碼。

2. 一切都集中在一項(xiàng)服務(wù)中。想象一下與組有關(guān)的代碼散布在整個(gè)應(yīng)用程序中。所做的每一次更改都需要到處進(jìn)行;至少可以說,這會有問題。

3. 代碼更加封裝。注意控制器createUserGroup現(xiàn)在不知道配額,只知道組創(chuàng)建,因?yàn)榕漕~無關(guān)緊要。

4. 我們可以專注于測試實(shí)現(xiàn),同時(shí)僅把細(xì)節(jié)層換成測試替代,使測試更容易。至于集成測試,我們可以替換QuotaService和GroupService,并測試該特定控制器所實(shí)現(xiàn)的實(shí)現(xiàn)。

可能的應(yīng)用

抽象層可以通過許多不同的方式實(shí)現(xiàn),其中最常見的用例是:

1. 通過分離策略和細(xì)節(jié)創(chuàng)建更精簡的組件:如果變更和重構(gòu)很容易,您的代碼將通過時(shí)間的考驗(yàn)。分離策略和細(xì)節(jié),同時(shí)僅用接口保持組件之間的交互提供了未來代碼演變所需的基礎(chǔ)設(shè)施。

2. 包裝第三方庫:您的代碼中過時(shí)的第三方庫阻止您升級其他依賴項(xiàng)是一場噩夢,如果該依賴項(xiàng)存在安全風(fēng)險(xiǎn),尤為糟糕。

通過在一個(gè)中央抽象層中使用您自己的接口包裝第三方庫,變得將很容易,因?yàn)樗鼈冎恍枰诒┞督涌诘哪且惶庍M(jìn)行。

3. 創(chuàng)建實(shí)用服務(wù):實(shí)用服務(wù)是提高開發(fā)速度和重用通用代碼段的關(guān)鍵方法。

比如說,如果您在開發(fā)處理大量不同時(shí)間和日期功能的特性,為什么不創(chuàng)建幾個(gè)實(shí)用函數(shù)來幫助您、并將它們放在一處供進(jìn)一步重用?

小結(jié)

創(chuàng)建抽象層通過提供三大好處來幫助顯著改進(jìn)代碼:集中、簡化和更好的測試。

請記住,抽象層和一般的抽象不是目的,而是實(shí)現(xiàn)目的的手段。抽象可能有缺點(diǎn)。一個(gè)常見的例子是某些抽象會影響性能。所以總是要先了解不足。

原文標(biāo)題:Why Your Code Needs Abstraction Layers,作者:Yair Cohen

【51CTO譯稿,合作站點(diǎn)轉(zhuǎn)載請注明原文譯者和出處為51CTO.com】

 

責(zé)任編輯:華軒 來源: 51CTO
相關(guān)推薦

2020-03-17 08:29:29

數(shù)據(jù)庫備份技術(shù)

2022-03-01 10:26:30

傳感器BMS物聯(lián)網(wǎng)

2020-07-16 11:23:54

應(yīng)用程序數(shù)據(jù)安全

2021-09-23 10:00:37

物聯(lián)網(wǎng)咨詢服務(wù)物聯(lián)網(wǎng)IOT

2018-04-12 08:28:42

數(shù)據(jù)中心大二層網(wǎng)絡(luò)服務(wù)器虛擬化

2011-02-16 09:42:04

DevOps

2020-05-29 10:17:00

代碼擴(kuò)展設(shè)計(jì)

2014-07-02 09:56:33

2020-11-30 10:02:27

云計(jì)算IT運(yùn)營工具

2020-04-29 15:30:22

CSP網(wǎng)頁前端

2015-04-16 15:42:21

關(guān)系型數(shù)據(jù)庫NoSQL

2022-06-28 14:54:26

加密貨幣數(shù)組貨幣安全

2022-06-07 10:09:20

5GRAN 架構(gòu)移動通信

2024-01-10 09:04:46

OSI網(wǎng)絡(luò)模型

2019-08-14 15:37:53

服務(wù)器虛擬化網(wǎng)絡(luò)

2024-12-23 13:00:00

MySQLMVCC數(shù)據(jù)庫

2021-01-05 22:36:32

5G低延遲網(wǎng)絡(luò)

2018-11-26 10:04:02

云遷移云供應(yīng)商數(shù)據(jù)

2023-06-13 17:37:55

人工智能智能家居

2022-01-10 08:00:00

云原生云計(jì)算技術(shù)
點(diǎn)贊
收藏

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