設計模式(單例模式,工廠模式,介面卡模式)
阿新 • • 發佈:2019-01-12
1:設計模式是什麼?
前人總結的一些經驗和思想,給我們提供了從抽象到具體的方法
總共有23種 分類: 建立型模式: 建立物件。(其實建立物件比較耗記憶體的動作) 結構型模式: 物件的組成。 行為模式: 物件能夠做什麼。 工廠模式: 通過一個工廠類來幫我們建立物件 單例模式: 要求:類在記憶體中的物件只有一個。 eg:印表機,網站訪問計數器。 如何實現單例設計模式: 分析: 1:讓外界不能通過構造方法建立物件。 將構造方法私有化。 2:類本身要建立一個物件 在成員位置建立一個物件 3:對外提供一個公共的方法可以獲取該物件
package com.thread.module;
public class Student {
//1:建構函式初始化為私有,防止外界直接通過建構函式建立物件
private Student() {
}
//6:由於靜態只能訪問靜態,此處也加上static
//7:為了不讓外界直接訪問加上 private
//2:提供一個物件
private static Student s = new Student();
//3:為了保證外界能夠獲取到物件,提供給外界的一個方法,
//4:但是此時還是訪問不到。因為該方法沒有加static只能通過物件獲取
//5:為了能通過類名獲取,加入static
public static Student getStudent() {
return s;
}
}
static修飾,隨著類的載入就載入
單例模式分類:
餓漢式:
一載入就建立物件(private static Student s = new
Student();)
就是上面的程式碼。
懶漢式:
用的時候才去建立
public static Student1 getStudent1() {
if (s == null) {
s = new Student1();
}
return s;
}
package com.thread.module;
/**
* 懶漢式
*/
public class Student1 {
private Student1() {
}
private static Student1 s = null;
public static Student1 getStudent1() {
if (s == null) {
s = new Student1();
}
return s;
}
public void show() {
System.out.println("懶漢式");
}
}
我們要掌握哪種方式呢?
開發:餓漢式
面試:懶漢式
為什麼?
因為餓漢式不會出現執行緒安全問題。
懶漢式:
延遲載入思想:(懶載入思想)伺服器啟動的時候載入的資源會少一點
執行緒不安全,你要給別人分析出安全問題的原因,並提供解決方案。
/**
* 此程式碼會產生執行緒安全問題
* 當有四個執行緒呼叫該方法
* t1,t2,t3,t4
* @return
*/
//5:解決:改為同步方法加synchronized
public synchronized static Student1 getStudent1() {
//1:t1,t2,t3,t4都進來了
if (s == null) {
//2:t1剛進入這裡,執行權就被t2搶到了,t2也進來了,同樣,t3,t4都進來了
//3:四個執行緒都建立了物件,導致執行緒不安全(雖然最後返回的就只有一個物件)
s = new Student1();
}
return s;
}
Runtime類本身就是一個餓漢式的體現,通過檢視原始碼可知。
public class Runtime{
private Runtime(){}
private static Runtime currentRuntime = new Runtime();
public static Runtime getRuntime(){
return currentRuntime;
}
}
//測試Runtime
public class RuntimeDemo {
public static void main(String[] args) throws IOException {
Runtime r = Runtime.getRuntime();
//可以調用出path路徑中配置過的exe檔案
r.exec("notepad");
}
}
介面卡模式
/**
*場景:
介面:Inter中有多個抽象方法
普通類:有一個方法,方法的形參是Inter介面
public void show(Inter i){}
測試類:建立普通類的物件呼叫方法。
*/
package com.thread.module;
/**
* 介面中的方法都是抽象的,不管你加沒加abstract,沒有加預設就adstract
*
*/
public interface Inter {
public abstract void show();
public abstract void show1();
public abstract void show2();
public abstract void show3();
}
public class InterDemo {
//方法的形式引數如果是介面,那麼傳遞的時候肯定是介面的子類物件,這就是多型。
public void show(Inter i) {
i.show3();
}
}
public class InterTest {
public static void main(String[] args) {
InterDemo id = new InterDemo();
id.show(new Inter() {
@Override
public void show3() {
System.out.println("show3");
}
@Override
public void show2() {
System.out.println("show2");
}
@Override
public void show1() {
}
@Override
public void show() {
}
});
}
}
在上面發現一個弊端。
在寫測試方法的時候,建立匿名Inner內部類的時候,會將所有的方法都重寫,這樣導致程式碼非常的難看,以及不簡介
改善:
怎麼實現?
介面中有多個方法
然後來一個抽象方法去實現這個介面。而且提供的都是空實現
最後在使用的時候,只需要重寫需要使用的那個方法就可以了。
package com.thread.module;
public abstract class InterAdapter implements Inter {
@Override
public void show() {
}
@Override
public void show1() {
}
@Override
public void show2() {
}
@Override
public void show3() {
}
}
//InterTest中修改
id.show(new InterAdapter() {
@Override
public void show3() {
System.out.println("show3");
}
});