在上篇,給大家介紹了簡單工廠、工廠方法、抽象工廠3種創建者模式,這3種設計模式如果沒真正理解,就很難弄清楚他們的區別。文章沒有采用大多數介紹設計模式的篇章介紹各個設計模式的優點、缺點、應用場景,原因是我看過很多關於這樣的文章,可是后來一點印象也沒有了,而且感覺越看越高深,思想本來挺簡單的。我想記錄我對設計模式的理解,記錄讓我真正對某一個設計模式豁然開朗的那種感覺。接下來我們看看創建型模式中的單例模式、建造者模式、原型模式。
1 單例模式
單例模式通俗一點講就是獨一無二的我,只提供一個訪問點給你訪問我。
例 1:一顆樹上有很多蘋果,那么蘋果這個類就有很多個實例了,所以不能用單例模式。
例 2:一個公司只有一個boss,那么任何職員需要和boss會話,都是和同一個boss會話。
從例2中我們知道,只有一個boss,boss需要提供一個讓所有的員工都找到他的方法,找到他就可以和他會話了。我們來UML建模看看。
根據上面的模型,我們來寫寫偽代碼:
單例模式最核心的思想就是把構造函數改為私有private,來實現有且僅有一個實例。
我們討論設計模式肯定是編程用的,所以我們會遇到多線程這些問題,那么在多線程的時候上面的代碼可能就不能保證Boss只有一個了,應為他們可能同時調用findMe,怎么解決這個問題呢?我們會想到加鎖。YES。加鎖之后如果一個線程A在訪問findMe,那么線程B就只能等待了,等線程A解鎖之后,線程B訪問findMe時由於對象已經創建,所以就不會再重復創建。我們來看看代碼:
上面這個代碼是由於有多線程這個概念所以我們進行了改進,和設計模式的思想沒有關系,看我們編碼的功底了。
高手看到上面加鎖的代碼是不是又有疑問了,當多線程訪問findMe()的時候,如果Boss這個實例不為null,由於加鎖的原因使得線程需要排隊來返回實例,是不是不好呢這樣,該怎么解決這個問題。這個好解決,我們判斷一下Boss是否為空,如果為空就加鎖,不為空就不加鎖,就可以解決這個問題了。改進代碼如下:
單例擴展:
上述的對象的創建都是在findMe中實現的,我們可不可以在Boss聲明的時候直接new呢?答案是可以的,首先我們了解一下sealed、readonly關鍵字。
readonly常量只能聲明為類字段,支持實例類型或靜態類型,可以在聲明的同時初始化或者在構造函數中進行初始化,初始化完成后便無法更改。
sealed 修飾符可以應用於類、實例方法和屬性。密封類不能被繼承。
單例另一實現方法如下:
2 建造者模式
建造者模式我的理解就是某某指揮某某做事情。
那我們就對某某指揮某某做事情進行UML建模吧。
下面我們來實現代碼:
首先有事情這個對象:
然后是工人相關的對象:
好啦,這些對象都創建好了,就剩下指揮者了,注意了指揮者是指揮某人做事情,這個也要表達出來,我們看看實現。
效果:
效果:
總結:只要我們清楚建造者模式表達的思想是某某指揮某某做事情,那么遇到相似的場景我們都可以用建造者模式,比如以前網上經常舉建造者模式例子 如麥當勞、肯德基,收銀員點餐、工作人員出餐就是這個思想。
3 原型模式
我們前面已經講了5種創建型模式了,最后還剩下原型模式。原型模式怎么理解呢?我想大家都知道克隆吧,就是復制一份或者多份一模一樣的出來。建模就這樣畫吧。
原型模式比較簡單,相信大家以前看過原型模式講解的例子也明白了,需要注意的就是淺拷貝與深拷貝的概念。聲明:這兩個概念和原型設計模式的思想無關,只是因為我們開發語言中有值類型和引用類型導致的。
淺拷貝:通俗一點講就是引用類型的對象不能被拷貝。
深拷貝:通俗一點講就是提供了引用類型對象不能被拷貝的解決方案。
我們來看看代碼:
淺拷貝克隆:
效果:
看到了吧,如果是淺拷貝,克隆的對象對引用進行賦值,都是對同一個引用對象進行賦值,所以顯示出來的結果也是一樣的。O(∩_∩)O~
深拷貝克隆:
為了達到真正的完全克隆,我們的解決辦法是把引用對象也進行克隆
調用:
效果:
看到上面的結果是否激動了一番,終於實現完美的克隆。好啦,創建型模式就講到這里了。
我們回顧一下創建型設計模式有哪幾種呢?
簡單工廠 這個工廠可以生產各種產品
工廠方法(為了解決簡單工廠中switch壞味道)
抽象工廠(為了解決幾個工廠同時生產某個產品的問題,同時給每個產品加上廠家說明)
單例模式 獨一無二的我,只提供一個訪問點給你訪問我
建造者模式 提供某某指揮某某做事情的模型
原型模式 提供克隆技術給你快速拷貝。
注:本文為作者原創,如下轉載請注明出處,http://www.cnblogs.com/programmerblog/admin/EditPosts.aspx?opt=1