摘要:我將描述我發(fā)現(xiàn)塑造成功框架的一些哲學(xué)。根據(jù)我的框架開發(fā)經(jīng)驗,我特此冷凝和總結(jié)我認(rèn)為任何成功的框架最重要的哲學(xué)?,F(xiàn)代框架往往是松散耦合的體系結(jié)構(gòu)。全??蚣芾缫呀?jīng)演變成由松散耦合的組件可以多帶帶使用或與第三方交換的框架。
來源:Philosophies that Shaped Successful Frameworks
在過去的十年里我們看到了許多軟件框架的出現(xiàn),像 Spring 和 Ruby on Rails 已經(jīng)是非常成功的框架了,掌握它們就意味著打開多扇就業(yè)機(jī)會的大門了。然而,對于每一個框架的成功,背后的大多數(shù)開發(fā)人員都不被人關(guān)注。2008年1月1日維基百科 列出了67個 Web 框架。然而今天,超過三分之二的消失在列表中或在三年內(nèi)沒有更新。作為 Yii 框架的創(chuàng)造者,我花了很多時間調(diào)查各種框架和理解為什么有些成功,有些失敗了。我將描述我發(fā)現(xiàn)塑造成功框架的一些哲學(xué)。
為什么框架?建立一個成功的框架,重要的是要了解什么是框架,開發(fā)人員為什么需要它們。
Douglas C. Schmidt 等人 認(rèn)為框架作為一個集成的軟件構(gòu)件(如類、對象和組件)集合,為相關(guān)應(yīng)用程序提供一個可重用的體系結(jié)構(gòu)。根據(jù)這一定義,
框架應(yīng)該是一個已完工的應(yīng)用骨架組成可重用和可定制的組件。開發(fā)人員將擴(kuò)展并定制一個框架通過提供他們的應(yīng)用程序和領(lǐng)域特定邏輯來形成一個完整的應(yīng)用程序。
一個框架典型的特征就是所謂的控制反轉(zhuǎn)(inversion of control)??蚣芡ǔ0缪葜M織主程序的角色和調(diào)用應(yīng)用程序代碼。這里是反過來的控制流——它調(diào)用我而不是我調(diào)用框架。下圖說明了框架之間的關(guān)系,函數(shù)庫,和應(yīng)用程序。注意框架通常提供現(xiàn)成的功能的庫,以幫助開發(fā)人員構(gòu)建應(yīng)用程序更快。
開發(fā)人員使用框架最重要的原因是框架如何提高生產(chǎn)力和幫助提高代碼質(zhì)量。例如,現(xiàn)代的框架(例如,django),經(jīng)常提供代碼生成工具或樣板幫助立即啟動新項目。此外,精心設(shè)計的框架內(nèi)嵌安全保護(hù)措施,幫助預(yù)防開發(fā)人員犯典型的安全漏洞。
企業(yè)使用框架,還有一個額外的好處是,它可以應(yīng)用在整個企業(yè),幫助執(zhí)行標(biāo)準(zhǔn)??蚣芴峁┝擞涗浤J?,詳細(xì)的設(shè)計和實現(xiàn)的工具用于在所有應(yīng)用程序之間提供一個一致的結(jié)構(gòu)。例如,在 Capital One (譯者注:薛強(qiáng)所在的公司) 我們開發(fā)一個 「Chassis」的框架作為一個集成的基礎(chǔ),統(tǒng)一了許多廠商和顧客公司內(nèi)部開發(fā)應(yīng)用程序的 API。
當(dāng)然,并不是所有的開發(fā)人員喜歡使用框架。一些一致的抱怨包括陡峭的學(xué)習(xí)曲線,框架耦合性比較高,性能較低,等等。今天,在這篇文章中我將為你解釋現(xiàn)代框架如何的解決這些問題,讓大多數(shù)的這些抱怨不再適用。
哲學(xué)像任何一個產(chǎn)品一樣,一個框架的成功取決于許多因素,包括其背后的思想,代碼質(zhì)量、文檔,周圍社區(qū),營銷,支持,等等。在我看來,特別重要的一項是考慮當(dāng)一個框架被設(shè)計和開發(fā)的哲學(xué)。
好久以前 Python 開發(fā)者 Tim Peters 開發(fā) Python 時發(fā)表了被稱為 Python 之禪 的二十格言設(shè)計原則?!簝?yōu)美勝于丑陋,明了勝于晦澀,簡潔勝于復(fù)雜……』他們鼓舞了許多類似的編程語言之禪(similar programming language zens),我發(fā)現(xiàn)這些格言是適用于框架設(shè)計的。根據(jù)我的框架開發(fā)經(jīng)驗,我特此冷凝和總結(jié)我認(rèn)為任何成功的框架最重要的哲學(xué)。
越簡單越好
整體設(shè)計是最糟糕的
一致性
明了勝于晦澀
約定大于配置
越簡單越好讓開發(fā)人員轉(zhuǎn)換一個新的框架從來都不是一件容易的事。然而,當(dāng)開發(fā)人員選用框架,會作為重點依靠它來投資當(dāng)前和未來的項目。此外,不想使用類庫 - 開發(fā)人員可以學(xué)習(xí)一個 API 實現(xiàn)它 - 學(xué)習(xí)框架要求開發(fā)人員在投入實際使用之前要充分理解框架規(guī)則。因此,重要的是要確保簡單的設(shè)計一個框架,使它更容易、有趣,而且容易去學(xué)習(xí),接受和利用。
為了實現(xiàn)簡單,一個框架應(yīng)該強(qiáng)制執(zhí)行一定數(shù)量的限制規(guī)則;同時,這些規(guī)則應(yīng)以統(tǒng)一的方式設(shè)計和有良好的文檔記錄??蚣軋?zhí)行更多的規(guī)則,陡峭的學(xué)習(xí)曲線,讓開發(fā)人員很難接受。當(dāng)規(guī)則是一致的,開發(fā)人員可以更快學(xué)習(xí)它們。沒有文檔,一個框架是無用的。因為沒有人會花時間反向工程其規(guī)則。
Express.js framework 框架路由語法規(guī)則的設(shè)計是一個很好的例子,一個非常受歡迎的 web 應(yīng)用服務(wù)器框架。而路由在 web 應(yīng)用程序中是一個重要的概念,是確定應(yīng)用程序如何響應(yīng)客戶端請求一個特定的端點(一個HTTP方法和一個URI)。Express.js 介紹一個簡單的規(guī)則來定義一個路線,app.METHOD(PATH, HANDLER),METHOD 是一個 HTTP 請求方法(例如 GET、POST),PATH 是服務(wù)器上的一個 URI 路徑,HANDLER 是回調(diào)函數(shù)路線相匹配時要執(zhí)行的。下面的代碼片段顯示了 Express.js 路由代碼的樣子。
var express = require("express"); var app = express(); // accept homepage request app.get("/", function (req, res) { res.send("Hello World!"); }); // accept POST request at /user app.post("/user", function (req, res) { res.send("Got a PUT request at /user"); }); // accept DELETE request at /user app.delete("/user", function (req, res) { res.send("Got a DELETE request at /user"); });
上面的代碼是不言自明的,因為它像是如何去看一個 HTTP 請求。因此,開發(fā)人員只需要很少的努力去學(xué)習(xí)就記住這個路由語法并且把它的實用性應(yīng)用到自己的項目中。
整體設(shè)計是最糟糕的這里的術(shù)語「整體」指的是以一個以緊密耦合的代碼庫為基礎(chǔ)構(gòu)建的框架。web 框架剛開始流行時,他們往往是一個整體,因為他們的主要目標(biāo)是提供全方位的快速的 web 應(yīng)用程序開發(fā)。漸漸地,人們意識到整體框架有很多問題。例如,
即使改變是框架完全無關(guān)的一小部分需要重新測試和釋放整個,從而導(dǎo)致應(yīng)用程序的框架要重建。實際上,整體框架的中代碼耦合使得它非常難以保持不同版本的向后兼容性。比如專業(yè)緩存、日志、數(shù)據(jù)庫,人們變得不那么愿意被綁定到一個單一的整體框架。
現(xiàn)代框架往往是松散耦合的體系結(jié)構(gòu)。全棧框架(例如 Spring )已經(jīng)演變成由松散耦合的組件可以多帶帶使用或與第三方交換的框架。專門的框架是有明確的契約,以支持更好的互操作性,這使得應(yīng)用程序不依賴于特定的框架。例如,一個非常受歡迎的 web 路由框架的特點是所謂『Sinatra-type 框架』,如 Sinatra,Express.js 和 Martini。這些框架使用以下中間件管道架構(gòu)支持請求路由和處理web應(yīng)用程序??蚣鼙旧硎欠浅P〉?但開放式體系結(jié)構(gòu)允許他們無限豐富的各種中間件組件。
一致性一致性意味著一個框架,堅持使用統(tǒng)一的設(shè)計,命名約定,代碼風(fēng)格,代碼組織等等。一個一致性的框架將降低門檻,因為用戶可以學(xué)習(xí)框架一個方面,并且應(yīng)用相同的模式,去快速學(xué)習(xí)其他的結(jié)構(gòu)。一致還可以幫助用戶減少框架特征錯別字或誤用的可能性。
例如,當(dāng)設(shè)計 Yii 框架的 query builder ,我們把一致性作為一個指導(dǎo)標(biāo)準(zhǔn)。查詢構(gòu)建器(query builder)允許您以編程方式創(chuàng)建一個數(shù)據(jù)庫無關(guān)的 SQL 語句,避免 SQL 注入攻擊。為了幫助用戶更容易地記住它的 API ,我們介紹了鏈?zhǔn)浇涌诤兔笙鄳?yīng)的 SQL 關(guān)鍵字的方法。下面的代碼片段顯示了如何使用 SQL 語句查詢構(gòu)建器設(shè)計。
(new Query()) ->select("id, email") ->from("user") ->orderBy("last_name, first_name") ->limit(10) ->all();
上面的代碼將生成和執(zhí)行 MySQL 聲明如下:
SELECT `id`, `email`FROM `user`ORDER BY `last_name`, `first_name`LIMIT 10
正如您可以看到的,代碼讀取非常類似于你編寫 SQL 語句。查詢構(gòu)建器之間的一致性和 SQL 語法很容易學(xué)習(xí)查詢生成器。
顯示大于隱式關(guān)于編寫自己的代碼顯式大于隱式,避免過多的使用 “自動魔法”,有兩個原因堅持這種哲學(xué)。首先,顯示的代碼更容易理解和維護(hù)。由于代碼是自解釋的,維護(hù)人員可能不是代碼的原作者,不需要來回跳轉(zhuǎn)找到實際上執(zhí)行的代碼。其次,顯示的代碼不容易出錯。雖然顯示的可能需要編寫更多的代碼行,它減少了看似簡單含蓄確籠罩著重要的代碼的情況。
看看下面的兩個 ORM (對象關(guān)系映射) 在 PHP 的代碼。他們都希望實現(xiàn)『訂單』數(shù)據(jù)庫記錄和『客戶』DB 記錄之間建立外鍵引用約束的相同的目標(biāo)。
$order->link("customer", $customer);
與
$order->customer = $customer;
第一個版本是正常的方法調(diào)用。第二個版本看起來更酷,因為復(fù)雜的數(shù)據(jù)庫連接操作可以通過一個看似簡單的任務(wù)來完成。然而,這是一種錯覺,第二個版本的簡單性是由其他地方的的復(fù)雜性隱藏掩蓋。例如,用戶不得不通過某種形式的文檔來學(xué)習(xí)這種特殊的賦值語法,以便在實踐中使用它。因為鏈接操作看起來像一個正常分配時,用戶可能會忘記處理由它引起的潛在的異常,從而導(dǎo)致整個程序發(fā)生故障。
事實上,Yii 的發(fā)展過程中,關(guān)于兩個版本我們討論了很多,并最終選定了第一個版本,它已收到投訴很少。
約定大于配置約定大于配置的概念已經(jīng)存在好多年了。這個想法是一個框架應(yīng)該采取堅持的公約,遵守約定同時仍然允許通過配置提高擴(kuò)展性。決策的目標(biāo)是減少開發(fā)人員需要做的數(shù)目,從而實現(xiàn)哲學(xué)# 1——簡單性。
約定大于配置最早在 Ruby on Rails 框架中開始流行。Rails 提供一個 ActiveRecord 庫,用類和數(shù)據(jù)庫中的表之間的映射處理。按照慣例,表名是類名的多元化形式。因此,該類賬戶將有一個表稱為帳戶。如果該表不命名這種方式,用戶將必須顯式配置類名和表名稱之間的映射關(guān)系。
許多 MVC 框架使用約定大于配置請求路由到特定的代碼片斷。如下圖所示,Sails.js framework 框架使用的約定,其中的 /we/say/hi URL請求將被路由到controllers/we目錄下 SayController 控制器類的hi 動作。按照本約定,開發(fā)人員不再需要對控制器的行為定義路由規(guī)則。但是,如果開發(fā)人員想要使用一個不同的路由規(guī)則,他們?nèi)匀豢梢酝ㄟ^顯式綁定一個路由到一個控制器動作。
約定優(yōu)于配置有助于減少需要編寫的代碼量。然而,它會給開發(fā)人員需要遵守規(guī)則引入了額外的成本。同時,也往往與前面討論的『顯示大于隱式』的哲學(xué)相沖突。事實上,雖然早期版本的 Spring 框架使用了似的 Sails.js 路由約定,Spring 現(xiàn)在要求開發(fā)者通過注釋明確指定映射。因此,當(dāng)決定是否引入新的規(guī)則以支持約定大于配置,應(yīng)采取明智的判斷。
總結(jié)建設(shè)一個成功的框架是所有關(guān)于功能和簡潔性之間的平衡。整個構(gòu)建框架的過程中,取舍經(jīng)常需要以堅守,并舉例說明,上述哲學(xué)加以考慮。
有時候,你可能會遇到其中一個理念是與另一個直接沖突的情況。一致性是比簡單更重要?在約定比顯性更重要?在這種情況下,請記住,一個框架的最終目標(biāo)是簡化開發(fā)人員的工作,并簡化代碼的編寫進(jìn)程。因此,保持它的簡單和直接。如果他們有明確性沖突,因為前者會帶來隱藏的復(fù)雜性可以犧牲約定。同樣,如果堅持一致性可以稍微違反嚴(yán)格會造成額外的并發(fā)癥。
Posted Dec 15, 2015 by...
Qiang Xue
軟件工程師LEAD、技術(shù)人員
首發(fā)地址:http://blog.forecho.com/successful-frame...
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/21371.html
摘要:當(dāng)?shù)貢r間年月日,北美首場路演及項目發(fā)布會在硅谷成功舉行,本次發(fā)布會由基金會發(fā)起,美國迦南公司不二空間協(xié)辦。是基于納什均衡和價值傳遞理論的新一代區(qū)塊鏈項目。 當(dāng)?shù)貢r間2018年8月29日,ETM北美首場路演及項目發(fā)布會在硅谷成功舉行,本次發(fā)布會由ETM基金會發(fā)起,美國迦南公司、不二空間協(xié)辦。 ETM首席經(jīng)濟(jì)顧問、諾貝爾經(jīng)濟(jì)學(xué)獎獲得者Thomas J. Sargent教授,ETM首席物理顧...
摘要:無數(shù)的模板語言和框架應(yīng)運(yùn)而生但是技術(shù)始終被分割為前端和后端。這意味著一個頁面可以有很多的這并不會對其余的頁面有任何影響。提前綁定和編譯預(yù)測是一個非常有效的部署方式。最后,這是我們對于這個特定問題的貢獻(xiàn)。 Next.js 原文地址 Naoyuki Kanezawa (@nkzawa), Guillermo Rauch (@rauchg) 和 Tony Kovanen (@tonykova...
摘要:人生,遠(yuǎn)不止是錢。如何管理,一個更復(fù)雜的人生人生,就是一個大型應(yīng)用。把復(fù)雜的人間,拆解成了行動與目標(biāo)。所以,,以及和兩個函數(shù),就構(gòu)成了的邏輯。現(xiàn)在,你不僅完全理解了的設(shè)計哲學(xué),你更懂得了如何管理人生。 Veux的哲學(xué),實質(zhì)上是人生的哲學(xué)。 看一看這張圖。 showImg(https://segmentfault.com/img/remote/1460000018782816?w=424...
閱讀 3331·2021-11-16 11:45
閱讀 4410·2021-09-22 15:38
閱讀 2855·2021-09-22 15:26
閱讀 3363·2021-09-01 10:48
閱讀 863·2019-08-30 15:56
閱讀 730·2019-08-29 13:58
閱讀 1497·2019-08-28 18:00
閱讀 2176·2019-08-27 10:53