本文主要是看了《設(shè)計模式》做的筆記和思考,在此分享僅代表個人觀點,如有不對的地方歡迎批評和指正。
Singleton(單例)模式
基礎(chǔ)
中心思想是全局只有一個該類的實例,相比全局變量它也有優(yōu)勢:單例模式不會污染命名空間。這種模式是巧妙地利用機制保證了其實例的唯一性,比如我們Java教材上的一個例子:
class Sun{
private static Sun sun;
protectc Sun(){}
public static Sun initialize(){
if(sun == null){
sun = new Sun();
}
return sun;
}
}
使用時如下:
Sun onlyOne = Sun::initialize();
此處將Sun的構(gòu)造函數(shù)隱藏了起來,并提供了靜態(tài)方法initialize獲取Sun對象,這個Sun對象是靜態(tài)的,可以保證每次調(diào)用initialize都是返回。
Java中的Protected
由于Java奇怪的權(quán)限制度,Protected修飾的構(gòu)造方法將導(dǎo)致同一個包下的其他類可見,若使用Private修飾則子類也不可見,無法完成實例化。因此在同一個包下,使用Protected有可能出現(xiàn)直接new出單例的風(fēng)險,但是,通過initialize()得到的對象是不受影響的,因為它是一個靜態(tài)變量,從這個角度來說,單例也沒有完全被破壞。
單例模式在多線程下
感謝網(wǎng)友的提醒并提供了他的博客供我參考,多線程下,若兩個線程同時調(diào)用initialize()并都發(fā)現(xiàn)此時sun(上面的代碼)為空,那么就有可能破壞單例,比較好的辦法是加同步鎖,如下所示。
public static synchronized Sun initialize(){
if(sun == null){
sun = new Sun();
}
return sun;
}
等同于:
public static Sun initialize(){
synchronized(Sun.class){
...
}
}
不過這樣的聲明可能影響效率(如果這個構(gòu)造方法很大的話),因此可以選擇使用同步代碼塊解決,并且給它個鎖對象。其中,byte[0]就是個開銷很小的鎖對象,參考這篇文章得到。
class Sun{
private static byte[] lock = new byte[0];
public static Sun initialize(){
synchronized(lock){
if(sun == null){
sun = new Sun();
}
return sun;
}
}
}
Adapter(適配器)模式
基礎(chǔ)
該模式的作用是為了“使得原本由于接口不兼容而不能一起工作的那些類可以一起工作”,即將不兼容問題通過一個中間人解決。該模式有兩種類型:類適配器、對象適配器。相比之下,個人覺得對象適配器更加靈活,也更加常見(Android中經(jīng)常需要實現(xiàn)各種BaseAdapter)
類適配器
假設(shè)A、B是兩個不兼容的接口(因為Java中不能多繼承),C為類,則C會同時實現(xiàn)A、B兩接口,并解決不兼容問題。效果是以后使用時只用C類就好,此時C是類適配器。
對象適配器
假設(shè)A、B是兩個不兼容的接口,C為類,C實現(xiàn)了B接口,使用時需要將C實例化,C的對象負責(zé)向A提供其能夠接收的數(shù)據(jù),這個C的對象為對象適配器。有點像用電器和插座,你為了讓你的用電器能用上全世界的插座,你會買電壓轉(zhuǎn)換器。示例代碼如下:
interface A {
showData();
}
interface B {
int getCount();
Object getData(int pos);
}
class C implements B{
@override
int getCount(){
// 返回數(shù)據(jù)總數(shù)
return dataSize;
}
@override
Object getData(int pos){
// 從列表中獲取相應(yīng)位置的數(shù)據(jù),這里是TopicData的對象
return list.get(pos);
}
}
// 該類是用來展示帖子
class Topic implements A{
private B adapter;
void setAdapter(B adapter){
this.adapter = adapter;
}
@override
void showData(){
if(adapter == null){
return;
}
allNum = adapter.getCount();
// 根據(jù)總數(shù)產(chǎn)生相應(yīng)數(shù)量的顯示框
...
for(i = 0;i < allNum; i++){
// 將帖子的信息放入顯示框內(nèi)
TopicData topicData = (TopicData) adapter.get(i);
topicView.setData(topicData);
}
}
}
總結(jié)
Singleon(單例)模式旨在利用機制控制類的實例化過程以及其對象的數(shù)量,同時能夠避免使用“全局變量”。Adapter(適配器)模式的目的是打通兩個接口間的交互,解決兼容性問題的同時,保證了交互雙方代碼的穩(wěn)定,同時該模式也能夠使得結(jié)構(gòu)上具有較大的靈活性。
謝謝您的觀看。