05.20 深入淺出設計模式——從球賽中悟多例模式

摘要: 之前有講過單例模式,多例模式實際上可以看作是單例模式推廣。在多例模式中,多例類可以有多個實例,並且多例類要負責創建、管理並且向外提供自己的實例。

一、概念

之前有講過單例模式,多例模式實際上可以看作是單例模式推廣。在多例模式中,多例類可以有多個實例,並且多例類要負責創建、管理並且向外提供自己的實例。多例模式可以分為無上限的多例模式和有上限的多例模式,這裡我們只講有上限的多例模式,因為無上限多例模式與我們平時自己new對象沒啥區別。

所謂有上限的多例模式就是多例類中的實例是有一個上限的,就好比足球場上一個隊最多隻能有11個運動員同時在場上踢球是一個道理。下面我們就按這個場景來介紹多例模式。

二、使用場景

在工作中需要用到池概念的地方就可以用多例模式來實現,比如我們常用的數據庫連接池等。

三、結構

多例模式的結構和單例模式很相像,其實就是一個多例類,並不需要多餘的依賴關係。

四、實現

首先我們需要寫一個多例類,上面也有說到多例模式其實就是一個多例類,多例類寫起來也相當簡單:

public class Position { private static final Map<integer> POSITION_INFO; //裝場上位置信息的容器
private String duty; //每個位置在場上有它對應的職責
//先把5個位置分配出來(五人制足球在場上的五個位子和職責)
static {
Map<integer> map = new HashMap<>(); map.put(1, new Position("1號位職責:把守球門!")); map.put(2, new Position("2號位職責:左路防守並協助進攻!")); map.put(3, new Position("3號位職責:右路防守並協助進攻!")); map.put(4, new Position("4號位職責:中場推進與進攻組織!")); map.put(5, new Position("5號位職責:進攻!"));
POSITION_INFO = Collections.unmodifiableMap(map);
} //構造函數需要把當前位置的職責寫入
private Position(String duty) { this.duty = duty;
} //隨機返回一個位置
public static Position getInstance() {
Random random = new Random(); return POSITION_INFO.get(random.nextInt(POSITION_INFO.size()));//隨機拉出一個位置
} //返回指定位置
public static Position getInstance(Integer code) { return POSITION_INFO.get(code);
} //位置職責
public String dutyInfo() { return duty;
}
}/<integer>/<integer>

我們看到多例類中有一個容器用來裝所有位置信息,並且和單例模式一樣擁有一個私有的構造方法,這個私有的構造方法是用來防止外部再產生位置對象,從而滿足有上限這一條件。

我們還能看到位置類中對外提供了一系列方法來獲取到位置信息。

接下來我們通過測試類測試一下:

public class Test { public static void main(String[] args) {
Position position = Position.getInstance(2); //獲取2號位置信息
System.out.println(position.dutyInfo()); //打印2號位置職責
Position position2 = Position.getInstance(5); //獲取3號位置信息
System.out.println(position2.dutyInfo()); //打印3號位置職責
}
}

深入淺出設計模式——從球賽中悟多例模式

可以看出輸出的結果與我們預期一致。

五、優勢

同單例模式一樣,多例模式同樣減少了內存的開銷,不再頻繁的創建和銷燬對象。

六、侷限性

也和單例模式類似,多例模式沒有接口,不能繼承。多例類既要關心內部邏輯又要關心外部如何來實例化它,違背了單一職責原則。當然了,世界上沒有十全十美的模式,每個設計模式都有它適用的地方,只要我們的使用方式得當,那麼多例模式可以幫助我們寫出漂亮優雅的代碼。


分享到:


相關文章: