Home avatar

Miles Chou

天涯何處無幹話,何必要講實務話

Carbon(4)--擴充繼承類別的範例

今天來繼續看 Carbon 還有擴充哪些功能

Carbon 提供許多比較的方法,讓我們在判斷時間會方便很多。

這些方法相信許多開發者都有看過。即使沒看過,每一個方法也都有相對應的別名可以參考使用。

這些方法是基於上面的基本比較方法實作出來的。

這兩個方法是基於 DIFFERENCES 功能實作的。

這些方法因為非常語言化,所以用起來很方便。會這樣設計,是因為我們在平常用詞時,會不自覺使用這些字眼:「這日期過去了嗎?」「這日期是未來嗎?」「這日期是今天嗎?」等等。

而且都可以跟昨天提到的建構方法直接串接:

Carbon(3)--建構繼承物件的範例

昨天了解 Carbon 套件是利用繼承來擴充物件的行為,我們今天一起來看看它是怎麼設計的。

首先原始碼註解很明確的分很多實作區塊,如 GETTERS AND SETTERS,接下來會以這些區塊來說明它擴充的方法。

這個區塊的方法都是在建立物件,所以大部分都是靜態方法。

分為幾種類型:

  • 從 DateTime 實例轉成 Carbon 的建立方法(Carbon::instance()
  • 當要用 fluent style 時,官方建議使用靜態方法(Carbon::parse())來取代 new
  • 取得現在時間(Carbon::now()
  • 快速相對時間,如今天(Carbon::today())、昨天(Carbon::yesterday())、明天(Carbon::tomorrow())。
  • Carbon 支援的最大值(Carbon::maxValue())與最小值(Carbon::minValue()
  • 給「年月日時分秒」的建立方法(Carbon::create())與經過把關的建立方法(Carbon::createSafe()
  • 特定來源資料的建立方法(Carbon::createFrom*()
  • 從現有物件複製物件(Carbon::copy()

以下會挑幾個特別的方法做說明:

這個方法會先判斷是不是自己(Carbon)的實例,再決定要如何做事。

如果是的話會使用 clone,不過事實上改成使用 copy() 這樣也是可行的:

Carbon(2)--繼承並不萬惡

Carbon 本身並不複雜,它使用兩個物件,分別繼承了原生 PHP [DateTime][] 與 [DateInterval][] 類別,並實作了新的行為,讓它更好使用。

以下會翻 Carbon 1.22.1 版來說做明。

在學 Design Pattern 時,常會聽到要「多用組合,少用繼承」。繼承這麼可怕,怎麼至今大多數語言都支援呢?這表示,繼承雖然有風險,但能避開風險的話,它仍然是個好用的觀念。像 Carbon 就是一個很好的例子,使用繼承擴展功能後,反而受到大多數開發者的喜愛。

我們這幾天可以一起來看看 Carbon 怎麼安全地實作繼承。

物件導向設計原則中,其中有一個原則是--里氏替換原則,身為一個子類,如果要繼承家業的話,必須要把父類原本做的事做好才行,就算有想要改善或是調整,也不能破壞行為。

所以,首先我們來看 Carbon 類別繼承了 [DateTime][] 哪些實作,來了解它是改善調整,還是破壞行為。

使用 IDE 可以很清楚知道下面這些方法有做覆寫: