caterpillar 積分 3 編輯於

差別主要在於有沒有可參考的 self instance(無論是 Python 明確的 self 或 Java 隱含的 this)。

像 Python 或 JavaScript 可以指定 self instance 的語言中,區分方法與函式就沒什麼意義,高興怎麼叫就怎麼叫(Java 也可以透過 Reflection 來做)。

就語言實作層面來說,其實都類似,都是變數查找之類的,看是要明確的 self 或隱含地在環境物件之類的東西中找。

haocheng 積分 0

欸,奇怪了,這個網址好像可以: https://www.slideshare.net/mobile/secret/HGrQAl6k15RAlK

natsu 積分 0

6)如果使用了带有null值的引用类型变量,instanceof操作将会返回false

雖然很少會發生但還是要注意一下 ...

7)...... 但是你可能不知道,你可以使用静态方法来使用一个值为null的引用类型变量。因为静态方法使用静态绑定,不会抛出空指针异常。

原來這樣也可以呼叫靜態方法,不過 eclipse 也會顯示 warning message 提醒您不要這麼做!

一般都是直接呼叫靜態方法,不會再透過物件變數。

haocheng 積分 0

我之前都是用 WebUpd8 repository 安裝 oracle-java8-unlimited-jce-policy package 解決...

IngramChen 積分 0

u161 - Unlimited cryptography enabled by default

是可以 workaround 不過我覺得要去改 jdk 底下的東西部署上都會很麻煩

OpenJdk 好像一直都是 unlimited 的?沒試過不知道。

IngramChen 積分 0 編輯於

144 太舊了, 最近有個需求需要 161...

haocheng 積分 0

大家升級到 Spring Boot 2.0 的速度也太快了?!

haocheng 積分 0

IBM will partner with other members of the OpenJDK community to continue to update an OpenJDK Java 8 stream with security patches and critical bug fixes.  We intend to keep the current LTS version secure and high quality for 4 years. 

haocheng 積分 0

沒有耶,之前都是用 Oracle JDK ,想說換 OpenJDK 試試看現在的 project 能不能跑,沒想到 IDE 就卡關 XD

haocheng 積分 0

我在 Intellij Idea 裡面新增 JDK 的時候選 AdoptOpenJDK 下載的 OpenJDK 10 with Hotspot 會出錯,但是選 Oracle 官網下載的 Oracle JDK 10 就沒問題...

haocheng 積分 0

好想要有 apt repository 直接下載 XD

natsu 積分 0 編輯於

ps. data class 的欄位都是 public 的,所以這個例子有點封裝失敗。不過上面的重點是行為。

資料不能 reuse 倒也罷了,因為一個物件頂多十幾個欄位

可是行為若不能 reuse 就比較麻煩 ...

既然如此,就把整個與核心properties 無關的推導之值全部 interface 化吧,最後,單獨一個 Coordinate 的物件模型變成如此

不過要 Java 8+ 才能在 interface 上實作 method ...

還在用之前版本的可能還是需要用到繼承 ...

IngramChen 積分 2

另一個有名的例子是 java8 的 java.time 的設計。

LocalDate 和 LocalDateTime 並沒有繼承關係,明明 LocalDateTime 也有 year, month, day 等等欄位,意思也很像

IngramChen 積分 9 編輯於

這篇文只能舉小例子,不過

data class CoordinatePlace(
  val coordinate: Coordinate,
  val place: String)

我到這邊就會停了,不會再 refactor 下去。因為像是 place.coordinate.lng 多一層存取對我來說不會是個問題,(多到兩層以上我才會開始煩惱)。

kotlin 可以用 with , apply 等等工具減少很多不必要的 code,為了少一層開始抽 ICoordinate 不值得啊。(當然也可能是因為只能選小的範例)

-------

然後,有關繼承。OOP 寫久了之後,我的經驗是可以被設計有繼承的關係,通常是有類似的 行為,而不是有類似的資料。

也就是說,我不傾向因為它們有很多共同的欄位,所以就用繼承來解決程式碼重用。我最少得觀察到一個以上的行為、動作,才會開始思考繼承,而且通常會變成 interface (因為只有行為,沒有資料)

為什麼會有這種結論?因為共同欄位用繼承來重用程式經不起時間的考驗,只有設計初時可以用,等到加需求後就… 真的就是補丁硬改,改不動的就 workaround,那程式碼真是令人痛心。

-------

繼續以 Coordinate 為例, 假設我們有求兩個座標距離的需求:

data class Coordinate(... omit) {
   fun distanceTo(other:Coordinate): Double
}

然後有名稱的地點 CoordinatePlace 也要算距離,方法一是直接拿裡面的 coordinate 來求距離,方法二就是加上同樣的 method:

data class CoordinatePlace(val coordinate:Coordinate) {
   fun distanceTo(other:Coordinate): Double {
      return coordinate.distanceTo(other)
   }
}

方法二可以封裝 CoordinatePlacecoordinate 欄位 (欄位能少曝露就少曝露),到此,distanceTo 這個 method 就會有機會抽成一個 interface,因為它是 行為 ,然後有求距離需求的 class 實作它就行了。

這種不依賴 coordinate.lng 等等內部資料的高階行為才會有資格被抽出去,也因為 method signature 沒有牽扯到太多的資料欄位,所以未來擴充時有很大的彈性。

在設計 model 之間的互動時,應該要多依賴上面 distanceTo 這種高階的行為,而不是直接開內部欄位 .lng , .lat 給別的 model 算,沒有高階行為的 model,才是真正的 Anemic Domain Model。

ps. data class 的欄位都是 public 的,所以這個例子有點封裝失敗。不過上面的重點是行為。

IngramChen 積分 2 編輯於

多著咧:

stream().tl ---> stream().collect(Collectors.toList())

foo.ate ---> assertThat(foo).isEqualTo( )

foo.bar().gv ---> given(foo.bar()).willReturn( )

koji 積分 0

以前想的有點忘了,現在最常的還是 .sout, haha