說到設計模式,很多人都聽過什麼23中設計模式,或者一些常見的模式名稱,在Java中確實有23種設計模式,但是設計模式並不是隨着Java的開發而產生的,它是一套被反覆使用、多數人知曉的、經過分類的、代碼設計經驗的總結,是由無數的開發者總結出來的一些代碼經驗,針對一些比較特殊的場合。
使用設計模式的目的:爲了代碼可重用性、讓代碼更容易被他人理解、保證代碼可靠性。 設計模式使代碼編寫真正工程化;設計模式是軟件工程的基石脈絡,如同大廈的結構一樣;
現在我們介紹其中的兩種設計模式單例模式和代理模式
單例模式:該類的對象只能創建一個
以前在寫代碼時,我們可以在外面想創建幾個對象就創建幾個對象,但凡外界使用new 就可以創建新的對象,現在我們要杜絕外界使用new,不讓外界創建對象則私有化構造函數:
class Demo{
private Demo(){}
}
現在外界不能創建對象,那麼外界想要獲得該類的對象調用該類的方法如何解決呢?——在內部創建該類的對象,因爲內部可以調用構造函數,之前我們在介紹成員和靜態的特點中可知,定義在類中的本類對象要用static進行修飾,那麼就將創建的對象當做靜態的成員變量,且對外還是不可訪問的,即:
class Demo{
private static Demo d=new Demo();
private Demo(){}
}//在該類外用完進行釋放
Demo.d=null;
現在又有一個新問題,既然對象被靜態同時也被私有了,那麼外界要如何訪問該對象呢?——提供一個函數對外開放,函數裏面返回該類創建的對象,然後在外用類名調用該函數得到對象
class Demo{
private static Demo d=new Demo();//0x123
private Demo(){}
public static Demo getInstance(){
return d;
}
}
Demo d1=Demo.getInstance();
Demo d2=Demo.getInstance();
d1=null;
單利模式分爲兩種形式,即餓漢模式和飽漢模式。
餓漢模式
是直接先創建一個該類的對象,提供一個訪問的方法將該類創建的對象返回出來;
//單例模式-餓漢式
class Singleton{
private static Singleton s=new Singleton();
private Singleton(){}
public static Singleton getInstance(){
return s;
}
}
飽漢模式
則是,先定義一個該類的引用變量,在提供訪問的方法中先判斷該類引用所指向的對象是否存在,如果存在,則直接將該對象返回,不存在才創建該類的對象。
//單例模式-飽漢式
class Singleton{
private static Singleton s=null;
private Singleton(){}
public static Singleton getInstance(){
if(s==null){
s=new Singleton();
}
return s;
}
}
單例模式的好處:減少重複創建對象,從而節約內存
代理模式
代理模式其實就是一個代理人和委託人之間的關係一樣,就好比明星與他的助理之間的關係,比如某明星要開一場演唱會,具體的唱跳是由他自己實現,而舞臺的搭建和時間則是通過他的助理做好這一切,其中這個助理就是代理人,我們來看一下代碼的體現:
class Demo09{
public static void main(String[] args){
ZhuLi zl=new ZhuLi ("張靚穎"); //這裏找到一個助理,傳進一個名字,相應的就是誰的助理
zl.sing(); //調用方法
zl.dance();
}
}
interface Singer{ //定義一個歌手的接口
public void sing(); //每個歌手都會唱歌
public void dance(); //每個歌手可能會一點舞蹈
}
class ZhuLi implements Singer{ //定義一個助理類也實現了歌手的方法,這是一個代理人
Singer s; //定義一個接口的引用
ZhuLi (String name){ //創建助理對象時將相應的歌手名字傳進來就相當於找到了他相應的助理人
if(name.equals("王力宏")){
s=new WangLiHong(); //如果是王力宏,就創建一個王力宏的對象
}
if(name.equals("張靚穎")){ //如果是張靚穎,就創建一個張靚穎的對象
s=new ZhangLiangYin();
}
}
public void sing(){ //助理當中也會實現唱歌的方法,不過他只是一個通知者,通知舞臺和時間已經準備好,讓相應的對象去完成相應的任務
s.sing(); //這裏通知該對象去做唱歌這個任務
}
public void dance(){ //與上面同理
s.dance();
}
}
class WangLiHong implements Singer{ //定義一個WangLiHong類實現歌手的方法,這是一個委託人
public void sing(){ //這裏委託人會完成自己相應的任務
System.out.println("王力宏正在舞臺上給大家唱《大城小愛》");
}
public void dance(){
System.out.println("王力宏給大家來了一段舞蹈");
}
}
class ZhangLiangYin implements Singer{ /定義一個ZhangLiangYin類實現歌手的方法,這也是一個委託人
public void sing(){
System.out.println("張靚穎剛剛唱了一首《畫心》");
}
public void dance(){
System.out.println("張靚穎跳了一段名族舞");
}
}
所以使用代理模式要明確三點:
抽象角色:通過接口或抽象類聲明真實角色實現的業務方法。
代理角色:實現抽象角色,是真實角色的代理,通過真實角色的業務邏輯方法來實現抽象方法,並可以附加自己的操作。
真實角色:實現抽象角色,定義真實角色所要實現的業務邏輯,供代理角色調用
代理模式的優點:
(1).職責清晰
真實的角色就是實現實際的業務邏輯,不用關心其他非本職責的事務,通過後期的代理完成一件完成事務,附帶的結果就是編程簡潔清晰。
(2).代理對象可以在客戶端和目標對象之間起到中介的作用,這樣起到了中介的作用和保護了目標對象的作用。
(3).高擴展性