精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

Go 和 Java 對比學習:單例模式

開發 后端
雖然 Go 語言并非完全的面向對象語言,只提供了部分面向對象的特性,但一些設計模式還是可以使用的。這個系列嘗試講解在 Go 中使用設計模式,同時給出 Java 對應的版本,進行對比學習。

Java 是較典型的面向對象語言。如果說 C++ 是設計模式的發源地(GoF 的書使用 C++ 描述的),那么 Java 將設計模式發揚光大。設計模式,很多人可能工作中沒有用到,因為大部分人停留在寫面條式的業務代碼,從頭擼到尾,沒有設計可言。但實際上,只要你用心思考,這樣的場景下也是很有可能用上設計模式的。特別是,當系統復雜時,設計模式的作用會很明顯。

雖然 Go 語言并非完全的面向對象語言,只提供了部分面向對象的特性,但一些設計模式還是可以使用的。這個系列嘗試講解在 Go 中使用設計模式,同時給出 Java 對應的版本,進行對比學習。另外,我們的設計模式不會局限在 GoF 的 23 中設計模式之中。

在開始設計模式之前,有必要提一下面向對象的 SOLID 5 大設計原則:

名稱縮寫含義The Single Responsibility Principle(單一職責)S對象應該具有單一的職責。這也是 Unix 的設計哲學The Open/Closed Principle(開/閉原則)O對擴展開發,對修改關閉The Liskov Substitution Principle(里氏替換)L對象應該可以在不破壞系統的情況下被子對象替換The Interface Segregation Principle(接口隔離)I不應強迫任何客戶端依賴其不使用的方法The Dependency Inversion Principle(依賴倒轉)D高級模塊不應依賴于低級實現

遵循這樣的設計原則,你的系統會更好維護。

除了 SOLID 5 大設計原則,一些書上可能還會提到下面的設計原則:

  • 合成/聚合復用原則(Composite/Aggregate Reuse Principle):盡量使用合成/聚合,而不要使用繼承。這也是 Go 語言設計遵循的,基于此,Go 中沒有繼承。
  • 迪米特法則(LoD),又叫 最少知識原則:一個對象應當對其他對象有盡可能少的了解;一個軟件實體應當與盡可能少的其他實體發生相互作用。

在你日常的工作中,可以運用以上原則審視你的設計,改進你的設計。

今天先看第一個設計模式。

1、單例模式簡介

面向對象中的單例模式是一個常見、簡單的模式。

英文名稱:Singleton Pattern,該模式規定一個類只允許有一個實例,而且自行實例化并向整個系統提供這個實例。因此單例模式的要點有:1)只有一個實例;2)必須自行創建;3)必須自行向整個系統提供這個實例。

單例模式主要避免一個全局使用的類頻繁地創建與銷毀。當你想控制實例的數量,或有時候不允許存在多實例時,單例模式就派上用場了。

先看 Java 中的單例模式。

通過該類圖我們可以看出,實現一個單例模式有如下要求:

  • 私有、靜態的類實例變量;
  • 構造函數私有化;
  • 靜態工廠方法,返回此類的唯一實例;

根據實例化的時機,單例模式一般分成餓漢式和懶漢式。

  • 餓漢式:在定義 instance 時直接實例化,private static Singleton instance = new Singleton();
  • 懶漢式:在 getInstance 方法中進行實例化;

那兩者有什么區別或優缺點?餓漢式單例類在自己被加載時就將自己實例化。即便加載器是靜態的,餓漢式單例類被加載時仍會將自己實例化。單從資源利用率角度講,這個比懶漢式單例類稍差些。從速度和反應時間角度講,則比懶漢式單例類稍好些。然而,懶漢式單例類在實例化時,必須處理好在多個線程同時首次引用此類時的訪問限制問題,特別是當單例類作為資源控制器在實例化時必須涉及資源初始化,而資源初始化很有可能耗費時間。這意味著出現多線程同時首次引用此類的幾率變得較大。

2、單例模式的 Java 實現

結合上面的講解,以一個計數器為例,我們看看 Java 中餓漢式的實現:

  1. public class Singleton { 
  2.   private static final Singleton instance = new Singleton(); 
  3.   private int count = 0; 
  4.   private Singleton() {} 
  5.   public static Singleton getInstance() { 
  6.     return instance; 
  7.   }  public int Add() int { 
  8.     this.count++; 
  9.     return this.count
  10.   }} 

代碼很簡單,不過多解釋。直接看懶漢式的實現:

  1. public class Singleton { 
  2.   private static Singleton instance = null
  3.   private int count = 0; 
  4.   private Singleton() {} 
  5.   public static synchronized Singleton getInstance() { 
  6.     if (instance == null) { 
  7.       instance = new Singleton(); 
  8.     }    return instance; 
  9.   }  public int Add() int { 
  10.     this.count++; 
  11.     return this.count
  12.   }} 

主要區別在于 getInstance 的實現,要注意 synchronized ,避免多線程時出現問題。

3、單例模式的 Go 實現

在 Go 語言中如何實現單例模式,類比 Java 代碼實現。

  1. // 餓漢式單例模式 
  2. package singleton 
  3. type singleton struct {  count int 
  4. }var Instance = new(singleton)func (s *singleton) Add() int { 
  5.   s.count++  return s.count 

前面說了,Go 只支持部分面向對象的特性,因此看起來有點不太一樣:

  • 類(結構體 singleton)本身非公開(小寫字母開頭,非導出);
  • 沒有提供導出的 GetInstance 工廠方法(Go 沒有靜態方法),而是直接提供包級導出變量 Instance;

這樣使用:

  1. c := singleton.Instance.Add() 

看看懶漢式單例模式在 Go 中如何實現:

  1. // 懶漢式單例模式 
  2. package singleton 
  3. import ( "sync" 
  4. )type singleton struct { 
  5.   count int}var (  instance *singleton  mutex sync.Mutex)func New() *singleton {  mutex.Lock()  if instance == nil { 
  6.     instance = new(singleton)  }  mutex.Unlock()    return instance 
  7. }func (s *singleton) Add() int {  s.count++  return s.count 

代碼多了不少:

  • 包級變量變成非導出(instance),注意這里類型應該用指針,因為結構體的默認值不是 nil;
  • 提供了工廠方法,按照 Go 的慣例,我們命名為 New();
  • 多 goroutine 保護,對應 Java 的 synchronized,Go 使用 sync.Mutex;

關于懶漢式有一個“雙重檢查”,這是 C 語言的一種代碼模式。

在上面 New() 函數中,同步化(鎖保護)實際上只在 instance 變量第一次被賦值之前才有用。在 instance 變量有了值之后,同步化實際上變成了一個不必要的瓶頸。如果能夠有一個方法去掉這個小小的額外開銷,不是更加完美嗎?因此出現了“雙重檢查”。看看 Go 如何實現“雙重檢查”,只看 New() 代碼:

  1. func New() *singleton { 
  2.   if instance == nil { // 第一次檢查(①) 
  3.     // 這里可能有多于一個 goroutine 同時達到(②) 
  4.     mutex.Lock() 
  5.     // 這里每個時刻只會有一個 goroutine(③) 
  6.     if instance == nil { // 第二次檢查(④) 
  7.       instance = new(singleton) 
  8.     } 
  9.     mutex.Unlock() 
  10.   } 
  11.    
  12.   return instance 

有讀者可能看不懂上面代碼的意思,這里詳細解釋下。假設 goroutine X 和 Y 作為第一批調用者同時或幾乎同時調用 New 函數。

  • 因為 goroutine X 和 Y 是第一批調用者,因此,當它們進入此函數時,instance 變量是 nil。因此 goroutine X 和 Y 會同時或幾乎同時到達位置 ①;
  • 假設 goroutine X 會先達到位置 ②,并進入 mutex.Lock() 達到位置 ③。這時,由于 mutex.Lock 的同步限制,goroutine Y 無法到達位置 ③,而只能在位置 ② 等候;
  • goroutine X 執行 instance = new(singleton) 語句,使得 instance 變量得到一個值,即對 singleton 實例的引用。此時,goroutine Y 只能繼續在位置 ② 等候;
  • goroutine X 釋放鎖,返回 instance,退出 New 函數;
  • goroutine Y 進入 mutex.Lock(),到達位置 ③,進而到達位置 ④。由于 instance 變量已經不是 nil,因此 goroutine Y 釋放鎖,返回 instance 所引用的 singleton 實例(也就是 goroutine X 鎖創建的 singleton 實例),退出 New 函數;

到這里,goroutine X 和 Y 得到了同一個 singleton 實例。可見上面的 New 函數中,鎖僅用來避免多個 goroutine 同時實例化 singleton。

相比前面的版本,雙重檢查版本,只要 instance 實例化后,鎖永遠不會執行了,而前面版本每次調用 New 獲取實例都需要執行鎖。性能很顯然,我們可以基準測試來驗證:(雙重檢查版本 New 重命名為 New2)

  1. package singleton_test 
  2. import ( "testing" 
  3.  "github.com/polaris1119/go-demo/singleton" 
  4. )func BenchmarkNew(b *testing.B) { 
  5.  for i := 0; i < b.N; i++ { 
  6.   singleton.New() }}func BenchmarkNew2(b *testing.B) { 
  7.  for i := 0; i < b.N; i++ { 
  8.   singleton.New2() }} 

因為是單例,所以兩個基準測試需要分別執行。

New1 的結果:

  1. $ go test -benchmem -bench ^BenchmarkNew$ github.com/polaris1119/go-demo/singleton 
  2. goos: darwin 
  3. goarch: amd64 
  4. pkg: github.com/polaris1119/go-demo/singleton 
  5. BenchmarkNew-8    80470467         14.0 ns/op        0 B/op        0 allocs/op 
  6. PASS 
  7. ok   github.com/polaris1119/go-demo/singleton 1.151s 

New2 的結果:

  1. $ go test -benchmem -bench ^BenchmarkNew2$ github.com/polaris1119/go-demo/singleton 
  2. goos: darwin 
  3. goarch: amd64 
  4. pkg: github.com/polaris1119/go-demo/singleton 
  5. BenchmarkNew2-8    658810392          1.80 ns/op        0 B/op        0 allocs/op 
  6. PASS 
  7. ok   github.com/polaris1119/go-demo/singleton 1.380s 

New2 快十幾倍。

細心得讀者會發現,在 Go 中,餓漢式還有一種更好的實現方式,那就是使用 sync.Once,這是 Go 實現懶漢式更標準的做法。核心代碼如下(New3):

  1. var once sync.Once 
  2. func New3() *singleton {    once.Do(func() { 
  3.         instance = new(singleton) 
  4.     })    return instance 

通過基準測試,它的性能和 New2 差不多。

此外,無論是 Java 還是 Go,都有一些其他“黑魔法”,比如 Go 語言中,利用 init 函數來初始化唯一的單例。不過一般都不太建議,還是常規方式來。

Go 語言單例模式,一般推薦優先考慮使用餓漢式。但如果初始化比較耗時,懶漢式延遲初始化是更好的選擇。

4、使用場景

在 Go 語言中,如下兩個場景比較適合使用單例模式:

  • 數據庫實例。只想創建一個 DB 對象實例,該實例在整個應用程序中使用。
  • 日志實例。同樣,只創建一個 Logger 的實例,并且在整個應用程序中使用它。

 

責任編輯:未麗燕 來源: 今日頭條
相關推薦

2011-03-16 10:13:31

java單例模式

2010-02-26 14:58:14

WCF單例模式

2021-03-02 08:50:31

設計單例模式

2021-02-01 10:01:58

設計模式 Java單例模式

2022-09-29 08:39:37

架構

2013-11-26 16:20:26

Android設計模式

2016-03-28 10:23:11

Android設計單例

2021-09-07 10:44:35

異步單例模式

2021-02-07 23:58:10

單例模式對象

2022-06-07 08:55:04

Golang單例模式語言

2022-02-06 22:30:36

前端設計模式

2022-08-15 08:49:06

Go版本單例模式

2023-03-21 15:21:52

開發程序設計static

2024-03-06 13:19:19

工廠模式Python函數

2024-02-04 12:04:17

2015-09-06 11:07:52

C++設計模式單例模式

2016-10-09 09:37:49

javascript單例模式

2011-06-28 15:18:45

Qt 單例模式

2023-11-21 21:39:38

單例模式音頻管理器

2015-01-14 13:26:58

AndroidJava單例
點贊
收藏

51CTO技術棧公眾號

99久久国产综合精品女不卡| 国产字幕视频一区二区| 欧美日韩在线视频一区二区| 日本电影一区二区三区| 国产一区二区波多野结衣| 国模吧视频一区| 91精选在线观看| 一区在线电影| 四虎永久在线观看| 老司机精品视频导航| 日韩在线视频二区| www.17c.com喷水少妇| av在线网页| 国产精品天天摸av网| 国产高清精品一区| 精品一级少妇久久久久久久| japanese国产精品| 欧美tk—视频vk| 亚洲免费999| 中文在线а√在线8| 亚洲欧美另类久久久精品| 欧美日韩免费高清| 亚洲精选一区二区三区| 久久er精品视频| 一区二区三区高清国产| 超碰av在线免费观看| 男人天堂亚洲| 亚洲欧洲日产国码二区| 免费看成人午夜电影| 黄色av网址在线| 国产一区二区三区高清播放| 国产精品久久久久影院日本| 国产精品久久久久久久妇| 亚洲精品tv久久久久久久久久| 日韩一区国产二区欧美三区| 天天碰免费视频| 无码小电影在线观看网站免费| 久久久影视传媒| 国产视频在线观看一区| 精品黑人一区二区三区国语馆| 黄色成人91| 精品国内自产拍在线观看| 蜜臀久久99精品久久久久久| 国产视频一区二区在线播放| 欧美日韩五月天| 日本xxx免费| 在线观看黄av| 国产精品久久久久久久久免费桃花| 亚洲bt欧美bt日本bt| 一级特黄aaaaaa大片| 美女网站色91| 国产精品免费看久久久香蕉| 久久综合激情网| 欧美一区二区| 亚洲欧美中文日韩v在线观看| 亚洲免费av一区| 激情视频网站在线播放色| 午夜精品成人在线视频| www.国产在线视频| av免费在线视| 欧美日韩一区二区免费视频| 国产又粗又硬又长| 黄网页在线观看| 国产亚洲成av人在线观看导航| 亚洲一区二区三区sesese| 国产又黄又爽视频| 国产一区二区三区四区五区入口| 奇米影视亚洲狠狠色| 91丝袜一区二区三区| 天堂va蜜桃一区二区三区| 国产精品大片wwwwww| 91麻豆国产视频| 国产成a人亚洲精品| 精品国产91亚洲一区二区三区www 精品国产_亚洲人成在线 | 亚洲精品卡一卡二| 亚洲色图欧美| 色综合久久天天综线观看| 国产精品theporn动漫| 在线观看日韩| 欧美—级a级欧美特级ar全黄| www中文在线| 欧美精品自拍| 97人人爽人人喊人人模波多| 草莓视频18免费观看| 久久99国产精品免费| 国产精品影片在线观看| 国产成人麻豆精品午夜在线| 成人av免费观看| 日韩欧美一区二区三区四区五区 | 久久在线视频在线| 国产一级特黄aaa大片| 狂野欧美一区| 91九色在线免费视频| 少妇激情av一区二区| 国产精品久久久久影院色老大| 丝袜美腿玉足3d专区一区| 精品美女在线观看视频在线观看| 欧美国产乱子伦 | 欧美午夜影院在线视频| 怡红院亚洲色图| 超碰一区二区三区| 亚洲精品不卡在线| 日本少妇aaa| 国产精品毛片在线看| 91九色精品视频| 久久经典视频| 亚洲国产美国国产综合一区二区 | 性欧美videos另类喷潮| 2019最新中文字幕| 国产黄色美女视频| 国产午夜一区二区三区| 亚洲狠狠婷婷综合久久久| 91caoporn在线| 中文字幕一区三区| av动漫在线观看| 视频一区在线| 日韩极品精品视频免费观看| 亚洲天堂网av在线| 性久久久久久| 狠狠色综合一区二区| caopeng在线| 欧美日韩激情一区| 性欧美精品中出| 亚洲一区久久| 国产精品一区二| 性xxxxfjsxxxxx欧美| 欧美中文字幕亚洲一区二区va在线 | 国产福利短视频| 日韩欧美视频在线播放| 欧美在线不卡区| 国内爆初菊对白视频| 亚洲人成网站精品片在线观看| 黄色a级片免费看| 亚洲福利影视| 色狠狠久久aa北条麻妃| 精品国产www| 床上的激情91.| 91麻豆天美传媒在线| 伊人久久综合网另类网站| 在线午夜精品自拍| 国产亚洲精品久久久久久打不开| 噜噜爱69成人精品| 欧美大陆一区二区| 国产精品va在线观看视色| 欧美三级韩国三级日本一级| 久久久国产一级片| 久久国产人妖系列| 一区二区三区在线观看www| 99久久婷婷国产综合精品首页| 精品sm捆绑视频| 国产一级久久久| 成人av综合在线| 美女av免费在线观看| 久操成人av| 国产精品久久久久久亚洲影视 | 精品国产乱码久久久久久久软件| 伊人免费在线| 欧美精品一级二级| 好吊日在线视频| 国产一区不卡在线| www.国产在线播放| 精品视频在线观看免费观看 | 欧美成人高清| 国产伦精品一区二区三区视频黑人| 日p在线观看| 欧美一区二区三区免费| 动漫精品一区一码二码三码四码| 麻豆精品在线视频| 99热这里只有精品7| 欧美最新精品| 久久精品视频免费播放| 亚洲黄色在线观看视频| 午夜精品久久久久| 青娱乐国产视频| 国产在线精品不卡| 国产3p露脸普通话对白| 亚洲伊人春色| 国产一区二区三区福利| 久久久久久免费网| 久热精品在线播放| 欧美91福利在线观看| 国产区一区二区| 日韩毛片一区| 欧美黑人又粗大| 久久久久久久影视| 制服丝袜国产精品| 99精品全国免费观看| 国产一区亚洲一区| 国产精品沙发午睡系列| 久久精品国产68国产精品亚洲| 国产91精品网站| 成人看片免费| 亚洲美女黄色片| 国产99久一区二区三区a片| 日韩欧美福利视频| 国产探花在线免费观看| 久久综合久久综合九色| 久久精品一二三四| 日韩精品亚洲一区| 少妇大叫太大太粗太爽了a片小说| 国产成人免费视频网站视频社区| 日韩视频免费观看| 天堂v在线观看| 动漫精品一区二区| www.av成人| 国产亚洲欧美中文| 日韩av卡一卡二| 亚洲精品四区| 佐佐木明希av| 北条麻妃国产九九九精品小说| 国产精品久久久久av| 国产一线二线在线观看| 欧美精品一区男女天堂| 在线免费看毛片| 欧美日韩性视频| 久久艹精品视频| 亚洲欧美在线视频观看| 日韩一区二区a片免费观看| 成人精品国产一区二区4080| 久久网站免费视频| 国产精品v日韩精品v欧美精品网站| 精品国产二区在线| 榴莲视频成人app| 国产日本欧美一区| 2019中文字幕在线电影免费| 亚洲欧美另类在线观看| 免费观看成年人视频| 9191精品国产综合久久久久久| 国产在线视频你懂的| 136国产福利精品导航| 99久久99久久精品免费看小说.| 国产一区二区精品久久99| youjizzxxxx18| 天堂精品中文字幕在线| 日av中文字幕| 亚洲主播在线| 欧美二区在线视频| 亚洲国产国产亚洲一二三| 黄色片免费在线观看视频| 久久久久国产| 五月天色婷婷综合| 国产精品黑丝在线播放| 亚洲欧美日韩在线综合 | 一区二区三区视频在线观看| 在线免费观看黄色小视频| eeuss国产一区二区三区| 久久久老熟女一区二区三区91| 日本视频一区二区| 不卡av免费在线| 亚洲欧洲日本mm| 黄页网站在线观看视频| 新狼窝色av性久久久久久| 欧美视频第三页| 免费成人在线观看视频| 超碰成人在线播放| 国产乱人伦偷精品视频免下载| 老熟妇仑乱视频一区二区| 久久国产免费| 在线免费视频一区| 精久久久久久久久久久| 免费黄频在线观看| 日本午夜精品视频在线观看| 久久撸在线视频| 国产在线麻豆精品观看| 美女黄色一级视频| 经典三级在线一区| 天天影视色综合| 成人深夜在线观看| 亚洲一区二区三区蜜桃| 国产精品久久久久影院色老大| 亚洲av综合一区二区| 中文字幕免费不卡| 人妻少妇精品一区二区三区| 亚洲国产成人av网| 精品少妇爆乳无码av无码专区| 亚洲欧洲三级电影| 日韩激情一区二区三区| 色综合久久综合网97色综合| 亚洲无码久久久久| 欧美成人bangbros| 欧美日韩国产综合视频| 日韩中文字幕在线精品| 久久亚洲资源| 国产成人高清激情视频在线观看| 性欧美又大又长又硬| 国产精品一区二区久久久久| 成人在线黄色| 国产精品免费在线免费| 一区二区在线免费播放| 成人在线观看av| 性欧美xxxx免费岛国不卡电影| 乱一区二区三区在线播放| 久久亚洲专区| 2022亚洲天堂| 国产一区二区美女| 人人爽人人爽人人片| 一区二区免费视频| 亚洲天堂avav| 日韩电影中文字幕av| 深夜福利视频在线观看| 欧美成人久久久| 暧暧视频在线免费观看| 668精品在线视频| 四虎国产精品成人免费影视| 亚洲影影院av| 狠狠操综合网| 999在线观看视频| 黄色资源网久久资源365| 一本色道久久综合亚洲精品图片| 久久久久久黄色| 久久久精品国产sm调教网站| 亚洲成av人片在线观看| 国产精品一区二区人人爽| 亚洲欧美成人一区二区在线电影| 成人精品一区| 97成人精品区在线播放| 97久久综合区小说区图片区| 中文字幕欧美日韩一区二区| 国产精品99一区二区| 无尽裸体动漫2d在线观看| 91啪亚洲精品| 黄色片视频网站| 欧美日韩中文字幕精品| 九一国产在线| 2021久久精品国产99国产精品| 日本美女久久| 日本一区视频在线播放| 欧美1区视频| 中文字幕1234区| 中文字幕欧美三区| 午夜视频网站在线观看| 国产午夜精品理论片a级探花| 黄色片网站在线观看| 国产精品一香蕉国产线看观看| 草草视频在线一区二区| 五月天在线免费视频| 久久99久久99| 性色av蜜臀av色欲av| 午夜欧美大尺度福利影院在线看| 波多野结衣视频免费观看| 日韩午夜在线播放| a级网站在线播放| 国产日本欧美一区二区三区| 99热国内精品| 永久免费黄色片| 亚洲一区二区综合| 91好色先生tv| 欧美成人合集magnet| 日韩高清一区| 亚洲国产高清国产精品| 91久久亚洲| 免费看黄色aaaaaa 片| 日韩欧美一区二区在线| 国产高清美女一级毛片久久| 国产精品久久久久影院日本| 日韩aaa久久蜜桃av| 欧美 日本 亚洲| 久久精品无码一区二区三区| 日本熟妇成熟毛茸茸| 亚洲精品www久久久久久广东| 免费不卡av| 久久久久久久久四区三区| 日韩高清国产一区在线| 国产免费一区二区三区四区| 日韩视频免费直播| 欧美13一16娇小xxxx| 999热视频| 99精品视频网| 国产精品久久久视频| 欧美精品在线观看一区二区| 欧美伦理免费在线| 欧美日韩国产高清视频| 麻豆精品在线观看| 久久久久久久国产视频| 亚洲久久久久久久久久| а√在线中文在线新版| av资源一区二区| 午夜综合激情| 欧美xxxooo| 日韩电影第一页| 亚洲ww精品| 欧美 日韩 国产一区| 国产精品另类一区| 欧美一级淫片免费视频魅影视频| 欧美成人在线免费| 国产va免费精品观看精品| 日日摸日日碰夜夜爽无码| 国产午夜精品在线观看| 国产视频手机在线| 欧美成人精品不卡视频在线观看| 99热这里有精品| 国产极品粉嫩福利姬萌白酱| 自拍偷拍亚洲综合| 午夜视频在线播放| 57pao国产成人免费| 国产精品传媒精东影业在线| 性久久久久久久久久| 欧美大片日本大片免费观看| 亚洲成人av观看| 激情伊人五月天|