iOS 這種設計是適當的,明確區分了不可變的數據結構和可變的數據結構。不可變有時也叫只讀。 不可變是個約束限制,施加這種限制可以減少不確定性。比如:
doSomething(NSMubaleArray* array);
這樣的接口,doSomething 裏面就有可能修改 array 的內容,這樣當使用這種函數的時候,就需要考慮數據被修改應該怎麽辦?是不是應該先復制壹份,防止修改呢?這樣就多了不確定性。而這種接口:
doSomething(NSArray* array);
就沒有這個問題。
妳可能會說,我在實現 doSomething 的時候小心壹點,保證內部不會被修改,並且用註釋說明,調用這函數的時候不會被修改,這樣其它人使用的時候就不用復制了。但是這種小心是不可信的,有可能出錯就壹定會出錯。不應該想著寫註釋要他人註意,而應該想辦法從根源杜絕問題。
另外,不可變結構附帶有如下好處:
功能單壹,實現起來會更簡單。
沒有修改的數據的接口,就從根源防止了數據無意中被修改。
因為不會被修改,更容易被緩存復用。
因為不可變,只讀,多線程訪問的時候,也不會發生壹邊讀壹邊寫的情況,也就沒有同步的問題,也就不用上鎖。
閑話壹句,設計類接口的時候,功能並非越多越好,不要想著接口以後可能有用就先加上,而應該想著接口現在沒有必要,就直接去掉。這點可能跟初學編程的人想的不壹樣。有時還會嫌某個類接口太多,而會將其用另壹個類封裝起來,只提供少數接口。
其實不單是 iOS 開發,其它場合都會區分可變和不可變的。比如 C++ 中的 const。swift 中的 let, Java 中的 final ,打開文件指定是否可讀寫。這些都是施加約束限制,無限制的所謂自由意味著混亂。
知乎上看到的 我覺得解釋的挺合理的