国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務(wù)器之家:專(zhuān)注于服務(wù)器技術(shù)及軟件下載分享
分類(lèi)導(dǎo)航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|編程技術(shù)|正則表達(dá)式|

服務(wù)器之家 - 編程語(yǔ)言 - JAVA教程 - Android 單例模式 Singleton 簡(jiǎn)單實(shí)例設(shè)計(jì)模式解析

Android 單例模式 Singleton 簡(jiǎn)單實(shí)例設(shè)計(jì)模式解析

2020-07-15 12:24java教程網(wǎng) JAVA教程

這篇文章主要介紹了單例模式 Singleton 簡(jiǎn)單實(shí)例設(shè)計(jì)模式解析的相關(guān)資料,需要的朋友可以參考下

單例模式 Singleton 簡(jiǎn)單實(shí)例設(shè)計(jì)模式解析

前言

今天我來(lái)全面總結(jié)一下Android開(kāi)發(fā)中最常用的設(shè)計(jì)模式 - 單例模式。

關(guān)于設(shè)計(jì)模式的介紹,可以看下我之前寫(xiě)的:1分鐘全面了解“設(shè)計(jì)模式”

目錄

Android 單例模式 Singleton 簡(jiǎn)單實(shí)例設(shè)計(jì)模式解析

1. 引入

1.1 解決的是什么問(wèn)題

之前說(shuō)過(guò),設(shè)計(jì)模式 = 某類(lèi)特定問(wèn)題的解決方案,那么單例模式是解決什么問(wèn)題的解決方案呢?

含義:?jiǎn)卫?=一個(gè)實(shí)例;

解決的問(wèn)題:降低對(duì)象之間的耦合度

解決方法:?jiǎn)卫J剑磳?shí)現(xiàn)一個(gè)類(lèi)只有一個(gè)實(shí)例化對(duì)象,并提供一個(gè)全局訪問(wèn)點(diǎn)

1.2 實(shí)例引入

接下來(lái)我用一個(gè)實(shí)例來(lái)對(duì)單例模式進(jìn)行引入

背景:小成有一個(gè)塑料生產(chǎn)廠,但里面只有一個(gè)倉(cāng)庫(kù)。

目的:想用代碼來(lái)實(shí)現(xiàn)倉(cāng)庫(kù)的管理

現(xiàn)有做法: 建立倉(cāng)庫(kù)類(lèi)和工人類(lèi)

其中,倉(cāng)庫(kù)類(lèi)里的quantity=商品數(shù)量;工人類(lèi)里有搬運(yùn)方法MoveIn(int i)和MoveOut(int i)。

出現(xiàn)的問(wèn)題:通過(guò)測(cè)試發(fā)現(xiàn),每次工人搬運(yùn)操作都會(huì)新建一個(gè)倉(cāng)庫(kù),就是貨物都不是放在同一倉(cāng)庫(kù),這是怎么回事呢?(看下面代碼)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
package scut.designmodel.SingletonPattern;
 
 
//倉(cāng)庫(kù)類(lèi)
class StoreHouse {
  private int quantity = 100;
 
  public void setQuantity(int quantity) {
    this.quantity = quantity;
  }
 
  public int getQuantity() {
    return quantity;
  }
}
 
//搬貨工人類(lèi)
class Carrier{
  public StoreHouse mStoreHouse;
  public Carrier(StoreHouse storeHouse){
    mStoreHouse = storeHouse;
  }
  //搬貨進(jìn)倉(cāng)庫(kù)
  public void MoveIn(int i){
    mStoreHouse.setQuantity(mStoreHouse.getQuantity()+i);
  }
  //搬貨出倉(cāng)庫(kù)
  public void MoveOut(int i){
    mStoreHouse.setQuantity(mStoreHouse.getQuantity()-i);
  }
}
 
//工人搬運(yùn)測(cè)試
public class SinglePattern {
  public static void main(String[] args){
    StoreHouse mStoreHouse1 = new StoreHouse();
    StoreHouse mStoreHouse2 = new StoreHouse();
    Carrier Carrier1 = new Carrier(mStoreHouse1);
    Carrier Carrier2 = new Carrier(mStoreHouse2);
 
    System.out.println("兩個(gè)是不是同一個(gè)?");
 
    if(mStoreHouse1.equals(mStoreHouse2)){//這里用equals而不是用 == 符號(hào),因?yàn)?== 符號(hào)只是比較兩個(gè)對(duì)象的地址
      System.out.println("是同一個(gè)");
    }else {
      System.out.println("不是同一個(gè)");
    }
    //搬運(yùn)工搬完貨物之后出來(lái)匯報(bào)倉(cāng)庫(kù)商品數(shù)量
    Carrier1.MoveIn(30);
    System.out.println("倉(cāng)庫(kù)商品余量:"+Carrier1.mStoreHouse.getQuantity());
    Carrier2.MoveOut(50);
    System.out.println("倉(cāng)庫(kù)商品余量:"+Carrier2.mStoreHouse.getQuantity());
  }
}

結(jié)果:

?
1
2
3
4
兩個(gè)是不是同一個(gè)?
不是同一個(gè)
倉(cāng)庫(kù)商品余量:130
倉(cāng)庫(kù)商品余量:50

2. 單例模式介紹

2.1 解決的問(wèn)題(應(yīng)用場(chǎng)景)

沖突:從上面的結(jié)果可以看出,工人類(lèi)操作的明顯不是同一個(gè)倉(cāng)庫(kù)實(shí)例。

目標(biāo):全部工人操作的是同一個(gè)倉(cāng)庫(kù)實(shí)例

單例模式就是為了解決這類(lèi)問(wèn)題的解決方案:實(shí)現(xiàn)一個(gè)類(lèi)只有一個(gè)實(shí)例化對(duì)象,并提供一個(gè)全局訪問(wèn)點(diǎn)2.2 工作原理

在Java中,我們通過(guò)使用對(duì)象(類(lèi)實(shí)例化后)來(lái)操作這些類(lèi),類(lèi)實(shí)例化是通過(guò)它的構(gòu)造方法進(jìn)行的,要是想實(shí)現(xiàn)一個(gè)類(lèi)只有一個(gè)實(shí)例化對(duì)象,就要對(duì)類(lèi)的構(gòu)造方法下功夫:


Android 單例模式 Singleton 簡(jiǎn)單實(shí)例設(shè)計(jì)模式解析

單例模式的一般實(shí)現(xiàn):(含使用步驟)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Singleton {
//1. 創(chuàng)建私有變量 ourInstance(用以記錄 Singleton 的唯一實(shí)例)
//2. 內(nèi)部進(jìn)行實(shí)例化
  private static Singleton ourInstance = new Singleton();
 
//3. 把類(lèi)的構(gòu)造方法私有化,不讓外部調(diào)用構(gòu)造方法實(shí)例化
  private Singleton() {
  }
//4. 定義公有方法提供該類(lèi)的全局唯一訪問(wèn)點(diǎn)
//5. 外部通過(guò)調(diào)用getInstance()方法來(lái)返回唯一的實(shí)例
  public static Singleton newInstance() {
    return ourInstance;
  }
}

好了,單例模式的介紹和原理應(yīng)該了解了吧?那么我們現(xiàn)在來(lái)解決上面小成出現(xiàn)的“倉(cāng)庫(kù)不是一個(gè)”的問(wèn)題吧!

2.3 實(shí)例介紹

小成使用單例模式改善上面例子的代碼:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
package scut.designmodel.SingletonPattern;
 
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
 
//單例倉(cāng)庫(kù)類(lèi)
class StoreHouse {
 
  //倉(cāng)庫(kù)商品數(shù)量
  private int quantity = 100;
  //自己在內(nèi)部實(shí)例化
  private static StoreHouse ourInstance = new StoreHouse();;
  //讓外部通過(guò)調(diào)用getInstance()方法來(lái)返回唯一的實(shí)例。
  public static StoreHouse getInstance() {
    return ourInstance;
  }
 
  //封閉構(gòu)造函數(shù)
  private StoreHouse() {
  }
 
  public void setQuantity(int quantity) {
    this.quantity = quantity;
  }
 
  public int getQuantity() {
    return quantity;
  }
}
 
 
//搬貨工人類(lèi)
class Carrier{
  public StoreHouse mStoreHouse;
  public Carrier(StoreHouse storeHouse){
    mStoreHouse = storeHouse;
  }
  //搬貨進(jìn)倉(cāng)庫(kù)
  public void MoveIn(int i){
    mStoreHouse.setQuantity(mStoreHouse.getQuantity()+i);
  }
  //搬貨出倉(cāng)庫(kù)
  public void MoveOut(int i){
    mStoreHouse.setQuantity(mStoreHouse.getQuantity()-i);
  }
}
 
//工人搬運(yùn)測(cè)試
public class SinglePattern {
  public static void main(String[] args){
    StoreHouse mStoreHouse1 = StoreHouse.getInstance();
    StoreHouse mStoreHouse2 = StoreHouse.getInstance();
    Carrier Carrier1 = new Carrier(mStoreHouse1);
    Carrier Carrier2 = new Carrier(mStoreHouse2);
 
    System.out.println("兩個(gè)是不是同一個(gè)?");
 
    if(mStoreHouse1.equals(mStoreHouse2)){
      System.out.println("是同一個(gè)");
    }else {
      System.out.println("不是同一個(gè)");
    }
    //搬運(yùn)工搬完貨物之后出來(lái)匯報(bào)倉(cāng)庫(kù)商品數(shù)量
    Carrier1.MoveIn(30);
    System.out.println("倉(cāng)庫(kù)商品余量:"+Carrier1.mStoreHouse.getQuantity());
    Carrier2.MoveOut(50);
    System.out.println("倉(cāng)庫(kù)商品余量:"+Carrier2.mStoreHouse.getQuantity());
  }
}

結(jié)果:

?
1
2
3
4
兩個(gè)是不是同一個(gè)?
是同一個(gè)
倉(cāng)庫(kù)商品余量:130
倉(cāng)庫(kù)商品余量:80

從結(jié)果分析,使用了單例模式后,倉(cāng)庫(kù)類(lèi)就只有一個(gè)倉(cāng)庫(kù)實(shí)例了,再也不用擔(dān)心搬運(yùn)工人進(jìn)錯(cuò)倉(cāng)庫(kù)了!!!

2.4 優(yōu)點(diǎn)

  1. 提供了對(duì)唯一實(shí)例的受控訪問(wèn);
  2. 由于在系統(tǒng)內(nèi)存中只存在一個(gè)對(duì)象,因此可以節(jié)約系統(tǒng)資源,對(duì)于一些需要頻繁創(chuàng)建和銷(xiāo)毀的對(duì)象單例模式無(wú)疑可以提高系統(tǒng)的性能;
  3. 可以根據(jù)實(shí)際情況需要,在單例模式的基礎(chǔ)上擴(kuò)展做出雙例模式,多例模式;

2.5 缺點(diǎn)

  1. 單例類(lèi)的職責(zé)過(guò)重,里面的代碼可能會(huì)過(guò)于復(fù)雜,在一定程度上違背了“單一職責(zé)原則”。
  2. 如果實(shí)例化的對(duì)象長(zhǎng)時(shí)間不被利用,會(huì)被系統(tǒng)認(rèn)為是垃圾而被回收,這將導(dǎo)致對(duì)象狀態(tài)的丟失。

3. 單例模式的實(shí)現(xiàn)方式

3.1 一般情況

餓漢式(最簡(jiǎn)單的單例實(shí)現(xiàn)方式)

?
1
2
3
4
5
6
7
8
9
10
class Singleton {
  private static Singleton ourInstance = new Singleton();
 
  private Singleton() {
  }
 
  public static Singleton newInstance() {
    return ourInstance;
  }
}

應(yīng)用場(chǎng)景:

  • 要求直接在應(yīng)用啟動(dòng)時(shí)加載并初始化
  • 單例對(duì)象要求初始化速度非常快且占用內(nèi)存非常小

懶漢式

懶漢式與餓漢式最大的區(qū)別是單例的初始化操作的時(shí)機(jī)

  • 餓漢式:自動(dòng)進(jìn)行單例的初始化
  • 懶漢式:有需要的時(shí)候才手動(dòng)調(diào)用newInstance()進(jìn)行單例的初始化操作
?
1
2
3
4
5
6
7
8
9
10
11
12
13
class Singleton {
  private static Singleton ourInstance = null
 
  private Singleton() {
  }
 
  public static Singleton newInstance() {
  if( ourInstance == null){
    ourInstance = new Singleton();
    }
    return ourInstance;
  }
}

應(yīng)用場(chǎng)景:

  • 單例初始化的操作耗時(shí)比較長(zhǎng)而應(yīng)用對(duì)于啟動(dòng)速度又有要求
  • 單例的占用內(nèi)存比較大
  • 單例只是在某個(gè)特定場(chǎng)景的情況下才會(huì)被使用,即按需延遲加載單例。

3.2 多線程下的單例模式實(shí)現(xiàn)

在多線程的情況下:

  • 對(duì)于“餓漢式單例模式”:適用,因?yàn)镴VM只會(huì)加載一次單例類(lèi);
  • 對(duì)于“懶漢式單例模式”:不適用,因?yàn)?ldquo;懶漢式”在創(chuàng)建單例時(shí)是線程不安全的,多個(gè)線程可能會(huì)并發(fā)調(diào)用 newInstance 方法從而出現(xiàn)重復(fù)創(chuàng)建單例對(duì)象的問(wèn)題。

解決方案1:同步鎖

使用同步鎖 synchronized (Singleton.class) 防止多線程同時(shí)進(jìn)入造成instance被多次實(shí)例化。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Singleton {
  private static Singleton ourInstance = null
 
  private Singleton() {
  }
 
  public static Singleton newInstance() {
   synchronized (Singleton.class){
     if( ourInstance == null){
      ourInstance = new Singleton();
    }
   }
    return ourInstance;
  }
}

解決方案2:雙重校驗(yàn)鎖

在同步鎖的基礎(chǔ)上( synchronized (Singleton.class) 外)添加了一層if,這是為了在Instance已經(jīng)實(shí)例化后下次進(jìn)入不必執(zhí)行 synchronized (Singleton.class) 獲取對(duì)象鎖,從而提高性能。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Singleton {
  private static Singleton ourInstance = null
 
  private Singleton() {
  }
 
  public static Singleton newInstance() {
if( ourInstance == null){
 synchronized (Singleton.class){
   if( ourInstance == null){
     ourInstance = new Singleton();
     }
   }
 }
    return ourInstance;
  }
}

解決方案3:靜態(tài)內(nèi)部類(lèi)

在JVM進(jìn)行類(lèi)加載的時(shí)候會(huì)保證數(shù)據(jù)是同步的,我們采用內(nèi)部類(lèi)實(shí)現(xiàn):在內(nèi)部類(lèi)里面去創(chuàng)建對(duì)象實(shí)例。
只要應(yīng)用中不使用內(nèi)部類(lèi) JVM 就不會(huì)去加載這個(gè)單例類(lèi),也就不會(huì)創(chuàng)建單例對(duì)象,從而實(shí)現(xiàn)“懶漢式”的延遲加載和線程安全。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
class Singleton {
 
  //在裝載該內(nèi)部類(lèi)時(shí)才會(huì)去創(chuàng)建單例對(duì)象
  private static class Singleton2{
   private static Singleton ourInstance = new Singleton();
  }
  private Singleton() {
  }
 
  public static Singleton newInstance() {
    return Singleton2.ourInstance;
  }
}

解決方案4:枚舉類(lèi)型

最簡(jiǎn)潔、易用的單例實(shí)現(xiàn)方式,(《Effective Java》推薦)

?
1
2
3
4
5
6
7
8
9
public enum Singleton{
 
  //定義一個(gè)枚舉的元素,它就是Singleton的一個(gè)實(shí)例
  instance;
 
  public void doSomething(){
  
 
}

使用方式如下:

?
1
2
Singleton singleton = Singleton.instance;
singleton.doSomething();

5. 總結(jié)

本文主要對(duì)單例模式進(jìn)行了全面介紹,包括原理和實(shí)現(xiàn)方式,接下來(lái)我會(huì)繼續(xù)講解其他設(shè)計(jì)模式,有興趣可以繼續(xù)關(guān)注

感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!

原文鏈接:http://blog.csdn.net/carson_ho/article/details/52223097

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 午夜视频在线观看网站 | 亚洲免费视频一区 | 欧美日韩在线播放 | 久久黄色网 | 一区二区三区在线免费视频 | 精品国产欧美一区二区三区成人 | 日韩毛片 | 久久久国产日韩 | 狼人综干网 | 免费在线观看黄色 | 国产福利91精品一区二区 | 国产999精品久久久久久 | 欧美在线观看免费观看视频 | www.亚洲 | 国产小视频在线播放 | 天天爱天天操 | 成人免费xxx在线观看 | 中文字幕日韩欧美 | 亚洲免费一区 | 久久99精品国产99久久6尤 | 国偷自产av一区二区三区 | 精品96久久久久久中文字幕无 | 青青在线精品视频 | 亚洲成人第一网站 | 综合久久99| 精品一区二区电影 | 国产美女网站 | 国产精品久久久久无码av | 欧美日韩国产三级 | 国产成人在线视频 | 黄色毛片在线看 | 中文字幕一区二区三区在线观看 | 羞羞羞网站 | 日韩欧美一区二区三区在线观看 | 国产免费一区二区三区 | 日韩国产在线观看 | 亚洲福利一区 | 亚洲成人激情在线 | 亚洲成人观看 | 99免费视频| 欧美午夜精品久久久久久人妖 |