快速理解設計模式之創建模式(下)


在上篇,給大家介紹了簡單工廠、工廠方法、抽象工廠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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM