架構之美:教你如何分析一個接口?
任一項目中,接口都很多,理解接口就是一個個讀接口源碼嗎?

相信沒有人能把所有接口細節記住,
如何才能理清繁雜的接口呢?
找主線,看風格。
找主線,你需要找到一條功能主線,建立起對這個項目結構性的認知,而不是一上來就把精力放在每個接口的細節。你對細節部分的了解會隨著你對項目的深入而逐漸增加。而有了主線,就有著力點,可不斷深入。
但要學習的不只是這些接口的用法,要想從項目接口設計上學到更多,就需要關注它所引導的風格。
為什么要看風格?
它希望你怎樣使用它或二次開發。
還要維護項目的一致性,必須統一風格。不少項目里共存多種不同風格的接口,就是每個人都在各設計各習慣的接口,導致混亂。
這一講,我們就來一起來學習怎樣看接口,我選擇的項目是Ruby on Rails,因為它的接口設計風格是帶給我最多震撼的,無論是編程接口的優雅,還是開發過程接口的順暢。
看設計要先看模型。
Ruby on Rails模型
Rails是標準的基于MVC模型進行開發的Web框架,給行業帶來巨大沖擊的是它的接口設計。
Rails一個重要的設計理念就是約定優于配置,無需配置,按照缺省的風格就可以完成基本的功能,這樣的理念貫穿在Rails各個接口的設計中。
理解接口應該先找主線,找到項目主線的一個方法就是從起步走文檔開始,因為它會把項目最基本的用法展現給你,你可以輕松地找到主線。
Rails的起步走文檔做得就非常好,主線可以說是一目了然。它用了一個Web項目幫你介紹了Rails開發的基本過程,通過這個過程,你就對Rails有了初步的印象。
有了主線之后,我們就要開始從中了解接口的風格。Rails給我們提供的三種接口,分別是:
Web應用對外暴露的接口:REST API;
程序員寫程序時用到的接口:API;
程序員在開發過程中用到的接口:命令行。
接下來,我們就一個個地深入其中,了解它們的風格,以及它們給行業帶來的不同思考。
REST 接口
先說應用對外暴露的接口:REST API。REST如今已經成為很多人耳熟能詳的名詞,它把Web 的各種信息當作資源。既然是資源,它就可以對這些Web信息做各種操作,這些操作對應著HTTP的各種動詞(GET、POST、PUT、DELETE等)。
REST是為了糾正大家對HTTP的誤用。 REST剛出來的時候,開發者普遍覺得這是一個好的想法,但怎么落地呢?沒有幾個人想得清楚。
Rails對REST的使用方式做了一個約定。只要你遵循Rails的慣用寫法,寫出來的結果基本上就是符合REST結構的,也就是說,Rails把REST這個模型用一種更實用的方式落地了。
Rails.application.routes.draw do
...
resources :articles
...
end
在用Rails寫程序的時候,你只要添加一個resource進去,它就會替你規劃好這個資源應該如何去寫、怎么設計URL、用哪些HTTP動詞,以及它們對應到哪些方法。
$ bin/rails routes
Prefix Verb ? URI Pattern ? ? ? ? ? ? ? ? ?controller#Action
articles GET ? ?/articles(.:format) ? ? ? ? ?articles#index
POST ? /articles(.:format) ? ? ? ? ?articles#create
new_article GET ? ?/articles/new(.:format) ? ? ?articles#new
edit_article GET ? ?/articles/:id/edit(.:format) articles#edit
article GET ? ?/articles/:id(.:format) ? ? ?articles#show
PATCH ?/articles/:id(.:format) ? ? ?articles#update
PUT ? ?/articles/:id(.:format) ? ? ?articles#update
DELETE /articles/:id(.:format) ? ? ?articles#destroy
root GET ? ?/ ? ? ? ? ? ? ? ? ? ? ? ? ? ?welcome#index
看了Rails給你的這個映射關系后,你就知道自己該怎么寫代碼了。這就是一種約定,不需要你費心思考,因為這是人家總結出來的行業中的最佳實踐。只要按照這個規范寫,你寫的就是一個符合REST規范的代碼,這就是Rails引導的外部接口風格。
API 接口
我們再來看API接口。當年我接觸Rails時,最讓我感到震驚的是它的數據庫查詢方式,與傳統開發的風格截然不同,就這么簡單的一句:
Article.find_by_title("foo")
1
要知道,那個時候用Java寫程序,即便是想做一個最簡單的查詢,寫的代碼也是相當多的。我們不僅要創建一個對象,還要寫對應的SQL語句,還要把查詢出來的結果,按照一定的規則組裝起來。
而 Rails用一句輕描淡寫find_by就解決了所有的問題,而且,這個find_by_title方法還不是我實現的,Rails會替你自動實現。當我們需要有更多的查詢條件時,只要一個一個附加上去就可以了。
Article.find_by_title_and_author("foo", "bar")
1
從功能的角度說,這樣的查詢在功能上是完全一樣的,但顯然Rails程序員和Java程序員的工作量是天差地別的,就是不同的編程接口所造成的。
所以一個好的接口設計會節省很多工作量,會減少犯錯的幾率。因為它會在背后幫你實現那些細節。
而設計不好的接口,則會把其中的細節暴露出來,讓使用者參與其中。寫程序庫和寫應用雖然都是寫代碼,但二者的要求確實相差極大。把細節暴露給所有人,顯然是一個增加犯錯幾率的事情。
Rails的API接口讓人們開始關注API的表達性。比如,每篇文章可以有多個評論,用Rails的方式寫出來是這樣的:
class Article < ApplicationRecord
has_many :comments
...
end
而如果用傳統Java風格,你寫出來的代碼,可能是這個樣子的:
class Article {
private List
...
}
“有多個”這種表示關系的語義用has_many表示更為直白,如果用List ,你是無法辨別它是一個屬性,還是一個關系的。
Rails里面類似的代碼有很多,包括我們前面提到的find_by。所以,如果你去讀Rails寫成的應用,會覺得代碼的可讀性要好得多。
由于Rails的蓬勃發展,人們也開始注意到好接口的重要性。
Java后期的一些開源項目也開始向Rails學習。比如,使用Spring Data JPA的項目后,我們也可以寫出類似Rails的代碼。聲明一對多的關系:
class Article {
@OneToMany
private List
...
}
1
2
3
4
5
而查詢要定義一個接口,代碼可以這樣寫:
interface ArticleRepository extends JpaRepository
Article findByTitle(String title);
Article findByTitleAndAuthor(String title, String author);
}
當你需要使用的時候,只要在服務里調用對應的接口即可。
class ArticleService {
private ArticleRepository repository;
...
public Article findByTitle(final String title) {
return repository.findByTitile(title);
}
}
顯然,Java無法像Rails那樣不聲明方法就去調用,因為這是由Ruby的動態語言特性支持的,而Java這種編譯型語言是做不到的。不過比自己寫SQL、做對象映射,已經減少了很多的工作量。
Spring Data JPA之所以能夠只聲明接口,一個重要的原因就是它利用了Spring的依賴注入,幫你動態生成了一個類,不用自己編寫。
簡單,表達性好,這就是Rails API風格。
如果要創建一個新項目,你會怎么做呢?使用Rails,這就是一個命令:
$ rails new article-app
這個命令執行的結果生成的不僅僅是源碼,還有一些鼓勵你去做的最佳實踐,比如:
它選擇了Rake作為自動化管理的工具,生成了對應的Rakefile
它選擇了RubyGem作為包管理的工具,生成了對應的Gemfile
為防止在不同的人在機器上執行命令的時間不同,導致對應的軟件包有變動,生成了對應的Gemfile.lock,鎖定了軟件包的版本
把對數據庫的改動變成了代碼;
……
而這僅僅是一個剛剛生成的工程,我們一行代碼都沒有寫,它卻已經可以運行了。
$ bin/rails server
這就啟動了一個服務器,訪問 http://localhost:3000/ 這個 URL,你就可以訪問到一個頁面。
如果你打算開始編寫代碼,你也可以讓它幫你生成代碼骨架。執行下面的命令,它會幫你生成一個controller類,生成對應的頁面,甚至包括了對應的測試,這同樣是一個鼓勵測試的最佳實踐。
$ bin/rails generate controller Welcome index
總結
看接口的一個方法是找主線,看風格。先找到一條功能主線,對項目建立起結構性的了解。有了主線之后,再沿著主線把相關接口梳理出來。
Web應用對外暴露的接口:REST API;
程序員寫程序時用到的接口:API;
程序員在開發過程中用到的接口:命令行。
一個好的接口設計,無論是最佳實踐的引入,抑或是API設計風格的引導,都可以幫助我們建立起良好的開發習慣。
理解一個項目的接口,先找主線,再看風格。
API web前端
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。