這個建議來自Joshua Bloch的“Provide Programmatic Access to All Data Available in String Form”。我這裡以他的提綱為基礎然後結合自己的理解寫了這篇短文。
這個建議的意思是如果你寫一個模組就要把模組裡面可以公開的資料資訊以String形式提供給客戶。因為如果你不提供這樣的String提供者,那麼這個使用這個模組的客戶要得到一些這個模組資訊的時候會感到很不方便。更糟糕的是可能他自己去解析能夠得到的String資訊。很多時候這個String就是來自toString()的返回。
他舉了個例子就是java.lang.Throwable.getStackTrace()。
public class Throwable{<br /> public StackTraceElement[] getStackTrace() ;<br />}<br />public final class StackTraceElement{<br /> public String getClassName();<br /> public String getFileName();<br /> public int getLineNumber();<br /> public String getMethodName();<br /> public boolean isNativeMethod()<br />}
這裡的getStackTrace()就是很好的例子。當你抓到一個Throwable(一般就是Exception)就可以調getStackTrace()得到StackTraceElement數組,然後用迴圈把異常的詳細資料以String的形式展現出來。而且客戶還可以用StackTraceElement的函數對每個StackTraceElement來擷取資訊。如果沒有這個getStackTrace(),使用者就要自己從printStackTrace()裡面去解析異常的詳細資料,解析這個棧的確讓人很痛苦。如果說用toString(),您試一下,它只能打出當前棧頂元素的資訊。
這裡我認為值得強調的是2個地方,一個是"All Data Available"裡面的"All",另一個"Available"。先說All,因為你不能假設你的客戶代碼會永遠不訪問某個資料,因此要把所有的資料資訊都提供出來,也就是做+法。再說Available,這個意思是要存取權限最小化,這也是OO的一個原則,這就是個-法。舉個例子,譬如大家都知道ArrayList是由數組實現的,而這個數組的真實大小是小於等於size()的。這個時候要不要提供這個數組的長度的方法呢?當然不要,因為這不是List介面要求,對ArrayList來說使用者也不需要關心。
翻看自己以前寫過的代碼,啊,很多沒有遵循這個規則。有些是把所有資訊都寫到toString(),以至於客戶代碼要解析toString()的字元。還有些就算是寫了toString()也沒有涵蓋所有的公開資訊。很多資訊都是在客戶代碼裡面解析實現。因為這樣的String一般都是給人看的,所以這樣的痛苦的代碼都是在寫log的時候用的。當他們要在log裡面列印這個對象資訊的時候,get這個欄位,get那個欄位,然後判斷邏輯最後組成String。 這原本是這個類自己的職責。