成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

[譯]軟件的復雜性:命名的藝術(shù)

Integ / 317人閱讀

摘要:軟件的復雜性命名的藝術(shù)在計算機科學中只有兩件困難的事情緩存失效和命名規(guī)范。到目前為止,我們依然將看做為開發(fā)人員找不到合適命名的一種替代方式。

軟件的復雜性:命名的藝術(shù)

在計算機科學中只有兩件困難的事情:緩存失效和命名規(guī)范。
—— Phil Karlton

前言

編寫優(yōu)質(zhì)代碼本身是一件很困難的事情,為什么這么說?因為良好的編碼風格是為了能更好的理解與閱讀。通常我們會只注重前者,而忽略了后者的重要性。我們的代碼雖然只編寫一次,但是在閱讀復審時會閱讀許多次。

良好的編碼習慣可以提高我們的閱讀質(zhì)量,比寫作本身要輕松許多,我們可以站在宏觀角度看待問題,遠觀大局,而不失細節(jié)。首先我們需要理解、分析清楚某個問題,然后用特有的,高效的,言簡意賅的方式讓更多人明白。對我來說,應該明確的把軟件工程歸屬到社會科學領(lǐng)域。我們?yōu)檎l編寫代碼,難道不是為了人類嗎?(感覺原文作者裝的有點過)

向其他人傳遞我們的想法以及編程思想,這就是我們在編碼時要做的。

命名構(gòu)造

為了說明我們的第一個概念,首先來做一個游戲,游戲名為 “我們住在哪個房間?”,如下會為你提供一張圖片,請你說說看這是什么房間。

問題 1/3

從上面的圖片不難看出,這肯定是客廳。基于一件物品,我們可以聯(lián)想到一個房間的名稱,這很簡單,那么請看下圖。

問題 2/3

基于這張圖片,我們可以肯定的說,這是廁所。
通過上面兩張圖片,不難發(fā)現(xiàn),房間的名稱只是一個標簽屬性,有了這個標簽,甚至我們不需要看它里面有什么東西。這樣我們便可以建立第一個推論:

推論1:容器(函數(shù))的名稱應包含其內(nèi)部所有元素

可以將這個推論理解為 鴨子類型。如果有一張床?那么它就是臥室。我們也可以反過來進行分析。

問題:基于一個容器名稱,我們可以推斷出它的組成部分。如果我們以臥室為例,那么很有可能這個房間有一張床。這樣我們便可以建立第二個推論:

推論2:根據(jù)容器(函數(shù))的名稱推斷其內(nèi)部組成元素

現(xiàn)在我們有了兩條推論,據(jù)此我們試著看下面這張圖片。

問題 3/3

好吧,床和馬桶在同一個房間?根據(jù)我們的推論,如上圖片使我們很難立即做出判斷,如果依然使用上述兩條推論來給它下定義的話,那么我會稱它為:怪物的房間。

這個問題并不在于同一個房間的物品數(shù)量上,而是完全不相關(guān)的物品被認作為具備同樣的標簽屬性。在家中,我們通常會把有關(guān)聯(lián)的,意圖以及功能相近的東西放在一起,以免混淆視聽,所以現(xiàn)在我們有了第三條推論:

推論3:容器(函數(shù))的明確度與其內(nèi)部組件的密切程度成正比

這可能比較難理解,所以我們用下面這一張圖來做說明:

如果容器內(nèi)部元素屬性關(guān)聯(lián)性很強,那么我們更容易找到一個用來說明它的名字。反之,元素之間的無關(guān)性越強,越難以描述說明。屬性維度可能會關(guān)系到他們的功能、目的、戰(zhàn)略,類型等等。關(guān)于命名標準,需要關(guān)聯(lián)到元素自身屬性才有實際意義。跟著我的思路,我們將很快明白這一點。

在軟件工程方面,這個觀點也同樣適用。例如我們熟知的 組件,,函數(shù)方法服務,應用。羅伯特·德拉奈曾說過:“我們的理解能力很大程度與我們的認知相關(guān)聯(lián)”,那么在這種技術(shù)背景下,我們的代碼是否可以使閱讀者以最簡單的方式感知到業(yè)務需求以及相關(guān)訴求?

Example 1:HTTP 域與汽車

HTTP 自身是一個域環(huán)境,它包含著我們的網(wǎng)絡(luò)請求與響應狀態(tài)。如果我們把一個 Car 的組件放入它的內(nèi)部,那么我們不能再稱它為 HTTP了,在這種情況下,它會變得讓人困惑。

public interface WhatIsAGoodNameForThis {
    /* methods for a car */
    public void gas();
    public void brake();
    
    /* methods for an HTTP client */
    public Response makeGetRequest(String param);
}

Example 2:單詞的耦合

有一種常見的命名模式,在名稱時后綴附加上 Builder 或 er 一類的結(jié)束詞,例如:SomethingBuilder,UserBuilder,AccountCreator,UserHelperJobPerformer 等等。

例如上圖中的名字,我們可以推斷出三件事情。第一,在類名中使用動詞 Build 意味著它是具備功能性的。第二,它由兩部分組成,一個是 User 用戶,另一個的 Builder 構(gòu)造者,這意味著它們之間可能在封裝、維度歸類上存在歧義。第三,Builder 構(gòu)造者 可以在類內(nèi)部訪問 User 用戶 的相關(guān)邏輯、數(shù)據(jù),因為他們在同一緯度空間內(nèi)。

這一點與工廠模式很相似,有自己的應用場景,當它在我們的工程中泛濫使用時,這將會是一個很麻煩的問題。另外,需要提醒大家,在工廠模式中,并不一定需要有一個類,通過一個 createUser 的方法足矣很好的實現(xiàn)工廠模式的功能。

Example 3: 基類

讓我們先看幾個生活中真實的例子。首先是 i18n Ruby gem(它的類與方法名稱都是非常簡練)。

class Base
    def config
    def translate
    def locale_available?(locale)
    def transliterate
end

這里,Base 這個命名本身并沒有傳達太多含義,其中內(nèi)部結(jié)構(gòu)包含了配置、翻譯,區(qū)域設(shè)置,音譯。它們可以看似無關(guān)的聚合在一起。

Example 4: 命名與構(gòu)建

一個合理的命名可以引導我們構(gòu)建出更為嚴瑾的組件容器。如下例所示。

class PostAlerter
    def notify_post_users
    def notify_group_summary
    def notify_non_pm_users
    def create_notification
    def unread_posts
    def unread_count
    def group_stats
end

PostAlerter 從這個名字本身可以發(fā)現(xiàn),它意味著在內(nèi)部會做一些類似提醒通知的功能。然而,其中 unread_postsunread_count,group_status 并不在這個功能的主要范疇內(nèi),從這一點來看,這個類的名稱并不是很理想。我們可以將這個三個方法移動到一個名為 PostStatistics 的類中,這樣解耦后,事件功能會變得更加清晰,更可預測。

class PostAlerter
    def notify_post_users
    def notify_group_summary
    def notify_non_pm_users
    def create_notification
end

class PostsStatistics
     def unread_posts
     def unread_count
     def group_stats
end
Example 5: 奇怪的命名

在 Spring 框架中有一些例子,組件做的事情太多,其名稱都非常冗長奇怪。這里只舉一個例子(因為實在太多了):

class SimpleBeanFactoryAwareAspectInstanceFactory {
    public ClassLoader getAspectClassLoader()
    public Object getAspectInstance()
    public int getOrder() 
    public void setAspectBeanName(String aspectBeanName) 
    public void setBeanFactory(BeanFactory beanFactory)
} 
Example 6: 說說好的名稱

我們聊了許多不太合理的命名,在 D3 的 arc 中就有許多不錯的命名定義,例如:

export default function() {
      /* ... */
      arc.centroid     = function() { /* ... */ }
      arc.innerRadius  = function() { /* ... */ }
      arc.outerRadius  = function() { /* ... */ }
      arc.cornerRadius = function() { /* ... */ }
      arc.padRadius    = function() { /* ... */ }
      arc.startAngle   = function() { /* ... */ }
      arc.endAngle     = function() { /* ... */ }
      arc.padAngle     = function() { /* ... */ }

      return arc;
}

上面這個例子中,每一個方法都是完全有意義的:他們都是以 arc 開頭。并且他命名風格就像繪制下面的圖片一樣簡練,令人歡喜。

方法 1: 拆解

應用場景:當你不能為類或方法找到一個合適的命名,但是你知道如何拆解它們,并且期望給他們的組合找到一個好的名稱。

主要有兩個步驟:

分辨出他們之間的特點和概念

將它們拆分開

在床和馬桶這種特定耦合的場景下,為了拆解他們的不同之處,我們將床移動到左側(cè),將馬桶移動到右側(cè)。這樣我們便將兩個不同的事物分離開了。

當你不能為某個事物找到一個好的名稱時,也許是因為你所面臨的不止一件事物。不過現(xiàn)在我們已經(jīng)知道,對多個事物進行命名是一件非常困難的事情,當我們遇到這類問題時,不妨確認一下構(gòu)造這個事物的組成部分,以及動作行為。

事例:

我們現(xiàn)有一個未命名的類,其中包含了 request,reponse,headers,URLsbody,caching,timeout,把所有這些從類中拉取出來,我們剩下這樣一些組件:Request,Respone,HeadersURLs,ReponseBody,Cache,Timeout 等。如果我們已知這些類的名稱,那么我們可以確定這個類是用于處理 Web 請求的,HTTPClient 是一個不錯的 Web 請求組件的命名。

當我們編碼遇到困難時,先不要想著整體,先考慮一下局部細節(jié)。

方法 2: 發(fā)現(xiàn)新概念

應用場景:當一個類并不簡單或者內(nèi)容并不相干。

發(fā)現(xiàn)新的概念需要大量業(yè)務領(lǐng)域的知識,當軟件的命名和業(yè)務保持一致時,一個普遍的語言便建立起來,它允許來自不同專業(yè)領(lǐng)域的人來使用相同的語言。

方法 3: 分組標準

應用場景:當有一個好的命名,但是他們他們之間并不適合。

組件元素之前可以通過各種標準進行分組,譬如組件元素的物理性質(zhì),經(jīng)濟性,情感性,社會性以及軟件中最常用的功能。

在軟件工程中,我們傾向于按功能對組件元素進行分組。如果列出你的項目文件,你可能會看到像 controller/,models/adapters/,templates/ 等等目錄名稱,然后,有些時候,這些名稱組合在一起并一定適合,這也是重新評估模塊,重新定義,規(guī)劃命名的時候。

每個應用程序都有自己不同的上下文環(huán)境,每個模塊、每個類、每個方法也同樣都有。User 這個詞所代表的含義可以是操作系統(tǒng)用戶,或是一張數(shù)據(jù)表,也可以是一個第三方的服務憑證,不同的上下文環(huán)境,它所表示的含義不盡相同。

無意義的詞與新詞

多年以來,命名規(guī)范的演變上變得更具有意義,有更多的人來填補這個陳舊的空缺。

Helper,helpers 是一個支持應用程序?qū)崿F(xiàn)的主要方式。應用程序?qū)崿F(xiàn)與定義的標準是什么呢?應用程序中的所有內(nèi)容都應該支持并實現(xiàn)其主要目標。

在實踐中,它們被擊中在一個非自然的分組中,為一寫其他常用的操作提供可重用性。一般情況下,helpers 需要另一個組件元素的內(nèi)部數(shù)據(jù)的依賴。這種命名一般會在找不到合適的名稱時折中使用。

Base,許久之前,在 C# 中有需要繼承類的命名方式都是以 Base 命名。例如:汽車和自行車的父類都是 Base 而不是 Vehicle。盡管微軟提出建議去避免這類命名方式,但他依然影響了 Ruby 這門語言,其中最具代表性的是 ActiveRecord 類的繼承。到目前為止,我們依然將 Base 看做為開發(fā)人員找不到合適命名的一種替代方式。

變動調(diào)整后的 Base 含括了 CommonUtils,例如,JSON Ruby gem 的 Common 類具有 parse,generate,load 以及 jj 等方法,但這里 Common 真的具備它的含義嗎?

Tasks,在 JavaScript 社區(qū)興起了一種通過異步調(diào)用函數(shù)的方式,這種方式起源于 task.js,即使目前這個開源庫很少再被提使用,但是這個術(shù)語流傳了下來。

如果團隊中所有人都能清楚的理解它的含義,那是可喜的。但如果有新人加入團隊,并且他遇到了被拋棄在垃圾堆中的 60 年代便存在的古怪命名,那又怎么辦呢?

在我之前的項目工作中,曾遇到過這樣的一個類的命名,你們猜猜看,Atlanta,是的,亞特蘭大,操蛋的亞特蘭大。沒人知道或者可以告訴我為什么要起這么個名字,以及含義是什么。

參考資料

Cwalina,Krzysztof.2009,框架設(shè)計指南:可重用 .NET 庫的約定、慣用語和模式,第二版。 Boston: Pearson Education, Inc. 206。

Evans, Eric. 2003。域驅(qū)動設(shè)計:解決軟件核心復雜性。Boston: Addison-Wesley Professional。

原文鏈接:https://medium.com/hacker-dai...

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/22797.html

相關(guān)文章

  • []軟件雜性命名藝術(shù)

    摘要:軟件的復雜性命名的藝術(shù)在計算機科學中只有兩件困難的事情緩存失效和命名規(guī)范。到目前為止,我們依然將看做為開發(fā)人員找不到合適命名的一種替代方式。 軟件的復雜性:命名的藝術(shù) 在計算機科學中只有兩件困難的事情:緩存失效和命名規(guī)范?!?Phil Karlton 前言 編寫優(yōu)質(zhì)代碼本身是一件很困難的事情,為什么這么說?因為良好的編碼風格是為了能更好的理解與閱讀。通常我們會只注重前者,而忽略了后者...

    chunquedong 評論0 收藏0
  • []軟件雜性命名藝術(shù)

    摘要:軟件的復雜性命名的藝術(shù)在計算機科學中只有兩件困難的事情緩存失效和命名規(guī)范。到目前為止,我們依然將看做為開發(fā)人員找不到合適命名的一種替代方式。 軟件的復雜性:命名的藝術(shù) 在計算機科學中只有兩件困難的事情:緩存失效和命名規(guī)范。—— Phil Karlton 前言 編寫優(yōu)質(zhì)代碼本身是一件很困難的事情,為什么這么說?因為良好的編碼風格是為了能更好的理解與閱讀。通常我們會只注重前者,而忽略了后者...

    Lowky 評論0 收藏0
  • []軟件雜性命名藝術(shù)

    摘要:軟件的復雜性命名的藝術(shù)在計算機科學中只有兩件困難的事情緩存失效和命名規(guī)范。到目前為止,我們依然將看做為開發(fā)人員找不到合適命名的一種替代方式。 軟件的復雜性:命名的藝術(shù) 在計算機科學中只有兩件困難的事情:緩存失效和命名規(guī)范?!?Phil Karlton 前言 編寫優(yōu)質(zhì)代碼本身是一件很困難的事情,為什么這么說?因為良好的編碼風格是為了能更好的理解與閱讀。通常我們會只注重前者,而忽略了后者...

    daydream 評論0 收藏0
  • 】Seaborn教程(一) 管理圖表藝術(shù)

    摘要:原文管理圖表的藝術(shù)第一小部分有人翻譯過了,鏈接用和管理圖表樣式有五個預設(shè)好的主題和。如上文提到的,網(wǎng)格讓圖表的布局成為了查找大量信息的表格,并且白線灰底讓網(wǎng)絡(luò)不會影響代表數(shù)據(jù)的線的顯示。盡管主題非常簡潔,但是它更適用于數(shù)據(jù)元素較大的布局。 原文: http://web.stanford.edu/~mwaskom/software/seaborn/tutorial/aesthetics....

    andycall 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<