請求參數用string好還是數字好?
最近做項目的時候碰到一個問題:
伺服器端喜歡用string返回一些參數,比如用戶類型,伺服器返回的結果是:owner,member,none這三種結果。然後我本地代碼裡面做字元串比對來獲取到這個用戶是什麼類型。我感覺是不是伺服器端定義一個枚舉類型來區分這三個類型會比較好,比如 owner = 1,member = 2, none = 3,這樣會更好?但是有人跟我說肯定是用string好,易讀性要強。不知道知乎的各位是什麼看法?追加:看了前三位的回復,以及找了一些資深人士諮詢了一下,發現這個問題是跟公司項目管理能力息息相關的。不過@Ivony 說的好,當做一個token,這句話很受用。
反正目前我們都是返回字元串的,沒錯就是為了可讀性。
至於什麼字元串不標準,大小寫神馬的,這些完全是技術和管理的問題。如果管理混亂,用int更亂,因為字元串你還可以看出來錯了,而int你根本不知道啥意思。
說白了,任何一個字元串字面量如果要在兩個地方出現,就必須寫成一個const(或static readonly)的欄位,何況是用作協議的規範。
既然都是用的同一個字元串,那什麼大小寫空白等問題怎麼可能會存在?
既然伺服器端有一個固定的枚舉,那麼到底是1,2,3還是owner,member,none,本質上都是常量,常量和常量之間本來就沒區別,如果字元串會出問題,那麼換個格式照樣會出問題。所以,在沒有極端性能要求的情況下,我選擇可讀性更好的字元串。
關鍵在於,你要把這個字元串當成一個token而不是一個message,一個具備更好可讀性的token。
再補充一些好了。
即使是為了減輕傳輸性能負擔,我們也會傾向於採用代碼(縮減的字元串),而非毫無意義的數字序號,因為人對於代碼的記憶要比序號好得多。
但是有一個地方我是建議使用純數字編碼,那就是顯示給用戶看的錯誤編號。有兩個原因:其一是有些信息我們不想讓用戶知道的太具體。
其二是出現這種情況的時候,我們是需要用戶反饋這個錯誤給我們的,而用戶都是非專業人士,對於他們來說1012這樣的錯誤代碼,比invalid username這樣的信息更容易反饋給我們。後者會導致用戶在反饋問題的時候加入自己的一些看法,最終通過客服再轉回到技術部的時候,可能得到完全不同的反饋。例如用戶完全可能分不清invalid username和invalid user的區別,但是如果提供一個完全不知道是什麼意思的編碼,如1012,1053這樣的東西,那麼在用戶-&>客服-&>技術部門這個信息傳遞過程中,失真的可能性就降低很多了。兩全方案。個人引導的實際項目大量使用。
一請用:0 :owner , 1:member , 2:none...這樣。超過10 用 a:xxx.。
強調一點:實際冒號後面我基本就是一行把意思說清的內容,而不是一單詞。機器讀(即接收方程序判斷),從不管後面的字元串,如:case token[0] : "0" : ..... println token..."1" :
......二,多搞幾行代碼,很容易實現程序在充分調試後,完全 release 時,報文 『:』之後的內容被壓縮或完全消除。
三,前面談字元串易讀的意見中,似乎都沒人回答這個問題:一個採用項目自定的私有協議,兩個程序模塊之間的機器通信,需要對人類終生可讀嗎?網路程序調試時讓程序員痛苦:也許一年,一年後它要連續運行5年,5年後我敢確認,那些可讀字元串有極大的可能性,正好從字面上誤導你,讓你先入為主。只要時間夠長,依賴一個單詞來回憶這報文是什麼的效果,和有人設計數據欄位時,採用拼音首字母然後讓你猜一樣,好刺激。通用過程如下:
自信!owner嘛,這不寫著嗎?疑他? 怎麼和我理解的不太一樣。。。是不是當年那個傢伙搞錯了,我知道他英語很爛又愛英語,TM的。。。疑自:好像又沒錯呀。。是不是我自己理解錯了。。。四,說這個是項目管理問題的,個人認為,這正好弄錯了。項目管理控制不佳的,項目成員之間才會依賴於直接讀單詞字面意義。問題說的例子,我猜測前後端好像都是一家公司在開發。那麼好的項目管理此情況下必然有兩項工作存在:一是同定義,即前後端共用消息報文(包括token)的定義代碼,即一事不二源。二是文檔,特別是跨模塊對接開發工作,必然是的消息或介面的說明文檔先行。定義成數字是有前期記憶代價。但數字編號的好處就是精確無二義。想想完全只為了給人腦管理的學生為什麼要編學號,監獄為什麼給犯人編個數字型大小。為什麼不這個叫大臉強姦張,那個叫尖嘴偷竊李。。後者好像一說就能記著一輩子呀。。。
五,推論開,如果「直接能讀懂」這麼重要,那為什麼只把這個原則用到開頭的token?(補:後面有個匿名回答問得好:想易讀,你怎麼不用漢字呢?)著名的boolean,光有true和false字面量就很不足。男女?憑什麼真是男假是女?測試開關我就堅持用 ON和OFF。所有這一切都合理,前提就是要有定義一致和有檔可查。我做過項目經理,對不起我就是希望你讀出報文時,把文檔放邊上,慢慢地對著文檔寫switch..case。你說這樣做要多花了你一個小時,可是你知道嗎?六個程序員中都自信能猜出字元串的字面含義,五個人成功了,第六個人也成功了百分之99,留下那個百分之一帶來的偶發問題要解決,可能是五個小時起步價。簡而言之,所有程序員敢不對照文檔就寫事件派發代碼的,要麼是沒文檔,要麼項目管理就那樣。
六,說個小實例。項目管理不力,單元測試時,大膽直接寫字面常量 「null」.作判斷了,可是我們明明約定用「none」。。。出問題時,來了三個人圍觀,也沒有反應過來這傢伙寫錯了。因為都覺得這null一詞符合當時的上下文。但另一處用的是數字,沒錯,就是一個毫無可讀性的7,結果問題一出現時,邊上人都不看,頭都不抬,只一句:「你先查查是不是值弄錯了再說吧。。。」 這就是不把希望寄托在字面值的作用和目的。
七,歸納一下,要求內部消息報文的可讀性,事實上只在上線前出錯排查調試時存在需求。極端做法就是前頭說的,乾脆直接把報文分成調試模式和發行模式。靠一個單詞的作用不大,並且你必須終有一天要擺脫掉你用以方便調試所依賴的字元串(或其它任何字面量)附加信息,否則容易反受其亂。其它性能影響什麼的,傳輸長點其實不怕(因為網路傳包默認也有小包對齊),但高頻率字元串創建和比較操作是不值得的。
。。。。。。補充幾點使用枚舉或整數的額外好處,雖然小。。好處一:你就沒有要根據消息的某個範圍來處理工作的需要嗎?比如消息分組?某類的消息編號放在區間100到199,再一類放在200到299。或者列印日誌要做區分處理,或者事件處理需要分組過濾。。然後你簡單一個除法運算算出它的組別,一開始你沒覺得爽。。歪頭一看隔壁項目組正在討論如何給字元串的token加前綴以區分組別。。你居然暗爽了。好處二:事件派發時 要比粗暴的話。。算了,明天再寫。當然是enum了。。至於怎麼序列化那是另一個故事。。
字元串好。伺服器端也不搞枚舉,很多伺服器端的語言比如ruby就是返回一個:owner, :member之類的,這個不叫枚舉,就叫做symbol, 你怎麼辦?這個跟字元串是最接近的。沒錯,就可以理解為token。其實伺服器端怎麼實現那是伺服器內部的事情,規定的太細會導致束手束腳。枚舉,枚舉是啥?憑什麼owner要對應1,member要對應2,意義是什麼?多了太多不必要的約定了。
協同工作,作為介面,用string自己工程,內部參數,用enum
在沒有極端需求的情況下,明文比二進位好太多了。
但往往很多時候,會有很多極限的需求,那就且code且珍惜吧。用符號 / 關鍵字可破用什麼語言?當然是 Lisp 了(逃
我說了不算,還得你多用用數字枚舉,才能體會到數字帶來的奇妙之處
我也支持用枚舉,不過你問的是string和int,這2個裡面我支持int,因為string的返回大小寫什麼的。。空格什麼的。。沒有int好,至於可讀性,我想你們應該有數據字典吧
這种放枚舉好,後端寫東西有時候不講究,這種字串會遇到大小寫問題,不同人還真不一定按介面寫,出問題還不好調試。性能啥的就不說了。
放在我剛參加前幾年,我一定傳數字.現在我傾向默認傳字元串.倒不是因為字元串便於擴展,比如以後轉為結構化串之類的,而是看日誌的時候確實省事啊.畢竟實際下來,類似情況應該不少,都用code,看日誌的時候不直觀... 還是老了啊.但是最好還是明確一下以下幾個問題:
1.這個服務調用是超高頻的么?
2.在你們的性能評估里,網路帶寬會成為瓶頸么?如果是那種超高頻的,帶寬時刻很緊張的.那還是本著省內存的原則搞吧.1,什麼年代了,程序和程序之間通訊用什麼編碼,還要用「人類是否易讀」作為參考依據?
程序間通訊協議,本來就不是給人看給人讀的。這麼設計的人一開始就是沖著「我調試可輕鬆了呢,bug隨便出」,一開始就用寬鬆的標準要求自己。長此以往,不利於減少bug。話說你怎麼不用漢字呢?哦,這時又嫌逼格不夠高了吧?一開始就應該強制規範,程序和程序間交流必須用對人類不友好的格式,這樣反而促使程序員寫代碼的時候更認真,因為寫錯了調試的成本太大了。2,另外儲存、傳輸字元串比數字需要更多的空間,而把數字變成人機界面給人看信息時則需要有一個轉換過程。用數字還是用字元串就是個空間換時間還是時間換空間的問題,這方面應該按實際需求來考量。而且隨著CPU、硬碟、內存、寬頻、手機流量越來越便宜,省的那一點點時間/空間有可能沒什麼意義。相比之下,好像寬頻和手機流量降價速度太慢了,所以還是傾向於時間換空間吧~
3,當你傳過去的值有可能被對方當做一個主鍵存起來的時候,傳字元串很有可能會給以後的你或者你的繼任者帶來噩夢。這個問題我在cocochina看過了!也回答了!
找平衡,在可維護性和性能之間取一個平衡。
總之別太極端。string比較好,反正客戶端和服務端共用一分聲明;並且定義字元串會用整數編碼,用的時候用整數引用。一般都這麼玩吧
string顯然好一些。。。你用int,還是要搞個int到string的對照表,然後看著對照表來讀。。。
以後你對著3頁程序,一邊看if else 一邊對著對照表找數字的時候你就想著string的好了。你們都說用字元串好,我來說下字元串缺點占帶寬,內存大
返回序列化/json的對象,方便可讀。
推薦閱讀:
※先開發 iOS 應用好,還是先開發 Android 應用好?
※哪些程序在 App Store 里是被禁止的?
※sdk和open api有什麼區別?