做者:Soroush Khanlou,原文連接,原文日期:2017-01-12
譯者:Cwift;校對:walkingway;定稿:CMBgit
我常常觀察一個類型的實例變量,這樣我就能夠更深刻地理解這個類型設計的初衷。一旦你知曉該類型的底層結構,它的用法也就隨之浮出水面了。反之亦然:若是你沒看過一個對象內部成員的佈局狀況,那麼不可能準確把握該對象的功能。這種狀況對於蘋果的閉源類型尤爲明顯。github
一個很好的例子是 NSDate
類型。當我開始編程時,就試着去了解如何使用 NSDate
以及它全部的兄弟對象,好比 NSDateComponents
、NSDateFormatter
以及 NSCalendar
,那真是一段艱難的歲月。爲何你須要使用 NSCalendar
在本來的日期上增長兩天?這些類之間的邊界劃分讓人捉摸不定,這使得當你想要尋找某些特定的功能時,沒法準肯定位到某個具體的對象中。編程
對我來講,關鍵的啓示是理解 NSDate
在底層的真實面目,是什麼緣由使得部分功能散落到其餘類中。NSDate
只是一個花哨的包裝器。僅此而已,文檔也揭示了這一事實:swift
NSDate
對象封裝了單個的時間點,獨立於任何特定的日曆系統或者時區。數組
全部的 NSDate
都存儲了一個浮點數,這個浮點數表明了從 2001 年 1 月 1 日 00:00:00 UTC 起的秒數。這些秒數與時區、星期幾、月份、夏令時、閏秒或者閏年一點關係都沒有。若是所需的計算基於秒數就能夠完成,那麼它會在 NSDate
上進行。不然,就要藉助其餘的類型了。promise
列舉一下單純依靠這個浮點數能作的操做:比較(earlierDate
,laterDate
)、判斷相等以及計算時間間隔(依舊返回一個浮點數)。distantFuture
和 distantPast
也是顯而易見的,它們是以面向將來和過去兩個維度來計算出指望的時間(浮點數表示)。安全
對於其餘功能,你必須使用其餘的類和對象。例如,要及時地向一個時刻中增長一天的時間,能夠選擇向一個 NSDate
中增長 24*60*60
秒的方式,不過最好的方式是經過 NSCalendar
來操做,避免遇到夏令時間、閏秒/天的問題 ,以及其餘可能隨時間出現的非標準問題。這篇博客介紹了使用 NSCalendar
進行這些計算的狀況。佈局
由於 NSDate
不存儲日期中與咱們所指望的月份相關的任何信息,若是要更改該月份,則必須使用一個瞭解狀況而且可以把日期拆分紅各個「組件」的對象。爲此,咱們要用到 NSDateComponents
,看看你可否弄懂它內部存儲數據的方式。atom
當我在編寫我本身的 Promise 庫時,發現了另外一個有趣的例子,經過研究一個對象存儲屬性的佈局來了解該對象的性質。若是查看每一個 Promise 對象的存儲屬性,你會看到三樣東西:spa
public final class Promise<Value> { private var state: State<Value> private let lockQueue = DispatchQueue(label: "promise_lock_queue", qos: .userInitiated) private var callbacks: [Callback<Value>] = []
每一個 promise 都有它的當前狀態(如 .pending
,.fulfilled
或者 .rejected
),一個確保線程安全的隊列,以及當 promise 完成時或者被拒絕時調用的回調數組。
當我寫完這個庫時,看了一些 Signal
/Observable
的實現,看看可否理解它們。我發現 JensRavens/Interstellar 的實現是最直接的。我查看了這個庫中每一個 Signal
對象的實例屬性,發現了一個很是類似的結構:
public final class Signal<T> { private var value: Result<T>? private var callbacks: [Result<T> -> Void] = [] private let mutex = Mutex()
它包含了存儲當前狀態的部分,存儲回調的部分以及存儲線程安全原語的部分。順序有些不一樣,他們使用了互斥體而不是隊列,但原理是相同的。這兩種類型之間的惟一區別是語義上的:promises 能夠在完成時清除它們的回調(釋放本身以及捕獲的變量),而 signals 必須保持它們的回調。
我認爲這個原則也能夠幫助設計本身的類型。看看你正在處理的對象的屬性。每個屬性都有目的性嗎?它是否對該對象的總體特性有幫助?是否有些屬性在該對象的一些實例中可以用到,而在另外一些實例中用不到?若是是的話,這些屬性可能屬於其餘對象。確保類型的實例變量被嚴格控制而且充分利用,確保咱們的每個對象在應用中都有着明確的定位。
本文由 SwiftGG 翻譯組翻譯,已經得到做者翻譯受權,最新文章請訪問 http://swift.gg。