javaSE (三十八)設計模式 ( 單例設計模式(餓漢式/懶漢式)、簡單工廠模式、工廠模式、介面卡模式、模板方法設計模式)
阿新 • • 發佈:2018-12-16
1、單例設計模式(餓漢式/懶漢式):
概念:保證類在記憶體中只有一個物件
思路:
- 私有構造方法,其他類不能再訪問該構造方法了
- 建立本類物件(就在本類裡建立),將物件的應用作為成員變數,並私有靜態化(在這裡又分為餓漢式和懶漢式,餓漢式直接引用連線物件,而懶漢式在第二步先建立引用,在第三步用一個判斷語句,如果引用沒有連線物件,就建立一個,如果有了,直接返回該引用)
- 對外提供獲取物件引用的方法getClass()
餓漢式和懶漢式的區別:
- 餓漢式是空間換時間,懶漢式是時間換空間(不推薦)
- 在多執行緒訪問時,餓漢式不會建立多個訪問物件,而懶漢式會(也就是說餓漢執行緒安全,懶漢不安全,可以加個同步鎖synchronized)
程式碼例項:
package cn.xinhua;
public class ThreadTest {
public static void main(String[] args) {
/*
* 餓漢式
*/
class Singleton1 {
// 1. 私有構造方法,其他類不能再訪問該構造方法了
private Singleton1() {
}
// 2. 建立本類物件(就在本類裡建立),將物件的應用作為成員變數,並私有靜態化
private static Singleton1 s = new Singleton1();
// 3. 對外提供獲取物件引用的方法getClass()
public static Singleton1 getS() {
return s;
}
}
/*
* 懶漢式:單例的延遲載入模式
*/
class Singleton2 {
// 1. 私有構造方法,其他類不能再訪問該構造方法了
private Singleton2() {
}
// 2. 建立本類物件的引用(先不著急連結物件)
private static Singleton2 s ;
// 3. 對外提供獲取物件引用的方法getClass(),如果為引用為空就建立一個,不為空(已經建立過),就返回
public static Singleton2 getS() {
if(s == null) {
//多執行緒時有隱患,執行緒1等待,執行緒2等待,就會建立多個物件
s = new Singleton2();
}
return s;
}
}
/*
* 第三種單例模式,直接將引用final
*/
class Singleton3 {
// 1. 私有構造方法,其他類不能再訪問該構造方法了
private Singleton3() {
}
// 2. 建立本類物件的引用物件,直接final
private static final Singleton3 s = new Singleton3();
}
2、簡單工廠模式:
簡單工廠模式又叫靜態工廠方法模式,定義了一個具體的工廠類負責建立類的物件
- 優點:客戶端不需要再負責物件的建立,從而明確了各個類的指責
- 缺點:靜態工廠類需要負責所有物件的建立,,如果有新的物件增加,或者某些物件的建立方式不同,就需要不斷修改工廠類,不利於後期維護
程式碼演示:
建立一個AnimalFactory工廠類如下
(其中Dog和Cat都是抽象類Animal的子類,重寫了eat方法)
package cn.xinhua;
public class AnimalFactory {
public Animal createAnimal(String animal) { // 父類引用指向子類物件
if ("Dog".equals(animal)) {
return new Dog();
} else if ("Cat".equals(animal)) {
return new Cat();
} else {
return null;
}
}
}
再來個測試類:
package cn.xinhua;
public class AnimalFactoryTest {
public static void main(String[] args) {
AnimalFactory af = new AnimalFactory();
Dog an = (Dog) af.createAnimal("Dog");
System.out.println(an);
an.eat();
}
}
輸出:
cn.xinhua.Dog@70dea4e(還沒有重寫子類的toString方法,所以列印的是地址值)
狗吃肉
3、工廠模式:
工廠模式算是上面的簡單工廠模式的進階,更容易擴充套件,但也更復雜了
這裡將工廠變為動態的(相比於上面的靜態),將工廠類變為實現一個工廠類的介面,重寫creatAnimal的方法,這樣你每次增加一個動物,都需要實現一個對用的具體的工廠類,然後建立這個動物就用這個動物的工廠類(更加複雜了,但是就像印錢一樣,只能國家印,要建立物件只能繼承這個工廠類並重寫方法)
- 優點:客戶端不需要再負責物件的建立,從而明確了各個類的指責,如果有新的物件增加,只需要增加一個具體的類和具體的工廠即可(從Animal那裡繼承的子類和從Factory那裡實現的工廠),不影響已有程式碼,後期維護容易,增強了系統的擴充套件性,感覺就是你要開個廠就需要向國家這個最大的廠報備一樣
- 缺點:程式碼多程式碼多程式碼多
程式碼演示:
工廠介面:
package cn.xinhua;
public interface Factory {
public Animal createAniama();
}
Dog類的工廠類(實現了上面的工廠介面):
(每次建立一個物件都要相應地建立一個此類的工廠類)
package cn.xinhua;
public class DogFactory implements Factory {
@Override
public Animal createAniama() {
return new Dog();
}
}
再來個測試類:
先建立此類的工廠類物件,然後用這個工廠類物件建立此類的物件(好複雜,有毒!)
package cn.xinhua;
public class AnimalFactoryTest {
public static void main(String[] args) {
DogFactory dg = new DogFactory();
Dog dog = (Dog) dg.createAniama();
dog.eat();
}
}
輸出:狗吃肉
4、介面卡模式:
介面卡是實現了監聽器介面下面的抽象類,因為我沒有看GUI,所以就不用監聽器的概念了
定義:
- 通常介面中有很多個方法,而程式中不一定所有的都用得到,但又必須重寫,很繁瑣
- 介面卡簡化了這些操作,我們定義的類只要繼承介面卡,然後重寫需要的方法即可
原理:
- 介面卡就是一個類,實現了介面,重寫了其中的所有的方法,但方法都是空的
- 介面卡類定義成抽象的,因為建立該類的物件,方法都是空的沒有意義
程式碼例項:
package cn.xinhua;
public class AnimalFactoryTest {
//監聽器介面,就是有很多方法的介面
public interface Listen {
public void method1();
public void method2();
public void method3();
public void method4();
}
//介面卡
abstract class Middle implements Listen {
@Override
public void method1() {
}
@Override
public void method2() {
}
@Override
public void method3() {
}
@Override
public void method4() {
}
}
//繼承介面卡的類,不用實現監聽器中全部的方法了
class Men extends Middle {
public void method1() {
System.out.println(1);
System.out.println(2);
System.out.println(3);
}
}
}
5、模板方法設計模式:
具體看:
設計模式之 - 模板模式(Template Pattern)
其實就是分權,國家定義一個大概的方法/模板,不會面面俱到,然後地方上實現具體的做法,有點像類的繼承的思想,增加了程式碼的泛化能力