社群日將至,有必要跟大家介紹一下Pokémon Go檢索系統。
// 假設 Pokemon.query(condition)為一可以找出符合『condition』的寶可夢方法
在Linq中,上述在Darwin0616的寶可夢中檢索4星超夢
,透過 method chain:
IEnumerable<Pokemon> mc4query = darwin0616Pokemons.
Where(p => p.query("4*&超夢"));
嗯,乾淨俐落。不過不熟 Linq 的一定會問:
『Where這個方法找出的是Darwin0616的寶可夢中的什麼東西?有API參考嗎?
』
在Linq中,上述在Darwin0616的寶可夢中檢索4星超夢
,透過 query syntax:
IEnumerable<Pokemon> qs4query = from p in darwin0616Pokemons
where p.query("4*&超夢")
select p;
似曾相識的SQL語法,白話就是:
『從Darwin0616的寶可夢中
找出符合"4*&超夢
"條件
的所有寶可夢。』
Microsoft官方說法:『Query syntax and method syntax are semantically identical, but many people find query syntax simpler and easier to read. 』
直接翻譯給大家聽聽:
『Linq
中,query syntax
與 method chain
是等價相同的,但是研究發現大多數的人覺得 query syntax 較容易閱讀及理解
。』
為什麼 query syntax 較容易閱讀及理解
// 思考以下的 method chain
List<Pokemon> mc4query = darwin0616Pokemons.
methodA(...).
methodB(...).
...
methodZ(...).
.ToList();
光看到這種methodA、methodB、...的方法命名,就不知道到底『看到了什麼』,每個方法的命名都很重要。藉由Functional Programming
設計檢索功能,要能讓其他開發者能夠一目瞭然的讀懂檢索過程
,並不是一件容易的事。
再來,method chain的長度越長,最後的輸出結果是否為List<Pokemon>
就更讓人擔憂。
即使在沒有型態區分的javascript
中,在那麼長的method chain
後得到了一個true
結果,你/妳真的確定這個true
是預期的布林值,而不是被偷塞空白的true_
字串嗎?
在Pokémon Go中,不採用單一的檢索框
來檢索寶可夢
、朋友
、道館
,反而是獨立成三個
功能頁面。除了讓使用者更直覺地去檢索到要找的標的
外,在ORM(Object-Relational Mapping)
的設計架構下,也較容易去與資料庫進行交易,因為標的的種類已經在各個功能頁面中固定
了。
檢索功能的設計,標的明確
非常重要。用query syntax
的寫作方式可幫助共同開發者不易迷失標的
。
另外,不要把所有的檢索標的
塞在同一個檢索框或者檢索的頁面中進行檢索,使用者也能更直覺地檢索到他們要的東西。
本篇雖然用
Linq
來說明檢索時,用method chain
較好還是用query syntax
較好,
還提到ORM
,不過以上都是個人在開發這些軟體功能時,自己主觀會採用的技術,並非N社
實際採用的方式,在此聲明一下。