l

2012年11月16日 星期五

Creational Patterns要解決什麼問題(中)?

Nov. 14 13:56~15:30

image

圖片來源:http://www.fanboy.com/2006/10/clone-wars.html

***

寫完《Creational Patterns要解決什麼問題(上)?》至今過了一個多月,之後的這段期間大多在寫Scrum與Kanban的文章。為了11月-25、12月1日的「Design Patterns這樣學就會了:入門實作班」招生,照理講這段時間Teddy應該要強打Design Pattern才對啊,沒想到居然誤入歧途一直在寫敏捷方法的文章…Orz。今天「改邪歸正」,繼續完成這系列的文章的第二集。

上次提到在Java語言中至少有以下9種方式來產生一個物件,並介紹了1、2、6這三種產生物件的方式。

  1. 直接在需要產生物件的時候把物件給new出來,例如 List<String> list = new ArrayList<>();
  2. 用Reflection的方式來產生物件。
  3. 用clone(Prototype pattern)的方式來產生物件。
  4. 用Singleton pattern。
  5. 用Object Pool pattern。
  6. 用Simple Factory pattern。
  7. 用Factory Method pattern。
  8. 用Abstract Factory pattern。
  9. 用Builder pattern。

今天介紹第3、4、5這三種方式,以下簡單用一個圖來說明。

螢幕快照 2012-11-14 下午2.28.28

 

接下來討論一下,是何種Force導致我們選擇不同的Solution。

使用clone

  • 在設計階段你不知道所要產生物件的具體類別(備註:所以無法用 new XXX() 的這種方式來產生物件)。
  • 如果能夠經由已經產生好的物件來產生出新的物件,那麼就可以免去設定新物件狀態的步驟(備註:例如,在使用類似Visio這種繪圖軟體的時候,直接複製畫布上面某個圖型物件)。

使用Singleton

  • 在設計階段你知道所要產生物件的具體類別。
  • 你所要產生的物件,代表某種單一(而且通常是共享)的資源,例如檔案系統、I/O Port。
  • 這種單一資源物件,本身會紀錄某些狀態,
  • 針對這種單一資源,只需要產生一個物件來代表就可以了。如果產生多份物件但卻代表相同的資源,不只浪費記憶體,還要確保這多份物件狀態必須一致,會增加程式的複雜度。

使用Object Pool

  • 在設計階段你知道所要產生物件的具體類別。
  • 你會頻繁地產生某種物件,或是產生物件的過程成本很高(備註:例如,頻率地產生thread,或建立資料庫連線物件很花時間),而你想要節省產生物件的記憶體或是時間成本。
  • 物件所代表的資源有限,為了避免過度使用或是控制程式對於電腦資源的使用,你想要控制同時產生這些物件的個數。
  • 物件可以被不同的客戶端重複使用。

***

以上說明應該夠清楚了,最後再補充兩點:

  • 使用clone的方式來產生物件(突然想到星際大戰中的克隆人 挑眉質疑),就是GoF Design Patterns裡面提到的Prototype模式。Java語言已經內建支援clone,但是有一些實作上的細節要注意,可參考《Effective Java, 2nd》這本書。
  • 有人覺的Object Pool只是Singleton的「變形」,所以不需要單獨列出來討論。但是從pattern的角度來看,這的確是兩個不同的pattern。為什麼是兩個不同的pattern ?請鄉民們仔細比較一下這兩個pattern的Force,答案就很清楚了 轉動眼珠

***

什麼,還是不懂?Teddy最後指點一條明路:「Design Patterns這樣學就會了:入門實作班」早鳥優惠還有幾天的時間,想在軟體開發領域變強、了解pattern理論、學會應用design pattern並朝向架構師邁進的朋友請把握Teddy本年度最後一次的公開課程XD。

***

友藏內心獨白:為了生活還是要置入性行銷一下啊 挑眉質疑

3 則留言:

  1. Object pool具體的例子其實蠻多的,例如:thread pool或database connection pool,實作方法雖然很像,但還是有些差異。pool裡的物件彼此之間的狀態少有同步的問題,而且pool size是可以視情況在runtime中調整,上面都是實作上的差異,最重要的差異還是文中所提到的force (intent)。

    回覆刪除
  2. Teddy您好,

    發現這裡豐富的開發資源有一陣子,每幾天都會按時收看.

    想問個不知道算不算是Design Pattern的問題.

    假設一個系統裡面,使用有些物件可以直接new,某些物件則使用sample factory或factory method,需要先產生工廠再呼叫其Create();有些又用builder pattern需要先產生builder再產生Director然後產生物件.

    因為其建構的方式都不同,這樣會不會造成開發人員另外一種負擔,一是使用物件前都要先了解其產生方式、流程,讓開發門檻提高.
    二是如果某物件被某人改過(重構過)與用了不同的Pattern,其他使用者可能就跟著Update這個資訊.

    簡單的說,使用Design Pattern常會封裝複雜的流程,讓程式內的呼叫者更簡易.但有方法能封裝掉『使用pattern的技術與規則』讓『開發人員』也能夠更無差別的應用嗎?

    講起來有些抽象,但不知是否有人探討這樣的問題?

    回覆刪除
  3. Hi Rock:

    一個系統中用不同的 creational pattern 去產生物件我個人認為是很正常的事,只要不是誤用,應該不會譈開發人員造成負擔。

    關於『裝掉使用pattern的技術與規則讓開發人員也能夠更無差別的應用嗎?』這個問題,我不知道您的意思是不是希望開發人員不需要學習 pattern 就能夠使用 pattern? 如果是的話,我覺得好像有點困難耶 (如果成立我就不能開 Design Patterns 的課程賺錢了...Orz)。

    回覆刪除