1. 程式人生 > >javaSE (三十八)設計模式 ( 單例設計模式(餓漢式/懶漢式)、簡單工廠模式、工廠模式、介面卡模式、模板方法設計模式)

javaSE (三十八)設計模式 ( 單例設計模式(餓漢式/懶漢式)、簡單工廠模式、工廠模式、介面卡模式、模板方法設計模式)

1、單例設計模式(餓漢式/懶漢式):

概念:保證類在記憶體中只有一個物件
思路:

  1. 私有構造方法,其他類不能再訪問該構造方法了
  2. 建立本類物件(就在本類裡建立),將物件的應用作為成員變數,並私有靜態化(在這裡又分為餓漢式和懶漢式,餓漢式直接引用連線物件,而懶漢式在第二步先建立引用,在第三步用一個判斷語句,如果引用沒有連線物件,就建立一個,如果有了,直接返回該引用
  3. 對外提供獲取物件引用的方法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)

其實就是分權,國家定義一個大概的方法/模板,不會面面俱到,然後地方上實現具體的做法,有點像類的繼承的思想,增加了程式碼的泛化能力