一.3大類設計模式:建立型,結構型,行爲型。html
a.5種建立型模式:工廠方法,抽象工廠,單例,建造者,原型。編程
b.7種結構型模式:適配器,裝飾器,代理,外觀,橋接,組合,享元。設計模式
c.11種行爲型模式:策略,模板方法,觀察者,迭代子,責任鏈,命令,備忘錄,安全
狀態,訪問者,中介者,解釋器。多線程
注意:除上述3大類外,還有另2類設計模式:併發型,線程池。併發
二.設計模式6大原則:開閉,里氏代換,依賴倒轉,接口隔離,迪米特(最少知道),合成複用。jvm
a.開閉:對拓展開發,對修改關閉。程序進行拓展時,不能修改原有的代碼,咱們須要使用接口和抽象類。ide
b.里氏代換(LSP):面向對象設計的基本原則之一,對開閉原則的補充。任何基類能夠出現的地方,子類必定出現。子類繼承基類,不影響基類的前提下,增長新的方法與功能,基類代碼就得以被複用。函數
c.依賴倒轉:開閉原則的基礎,針對接口編程,依賴於抽象不依賴於具體。測試
d.接口隔離:使用多個隔離接口比使用單個接口好。
e.迪米特(最少知道):一個實體應該儘可能少的與其餘實體之間發生相互做用,使得系統功能模塊相對獨立。
f:合成複用原則:儘可能使用合成/聚合的方式,而不是繼承。
三.23種設計模式。
1.3種工廠方法模式:普通工廠,多個工廠方法。
a.普通工廠:創建一個工廠類,對實現同一接口的類進行實例建立的過程。
父接口:
public interface Sender{ public void send(); }
實現類:
public class MailSender implements Sender{ @Override public void send(){ System.out.println("this is mailSender!"); } }
public class SmsSender implements Sender(){ @override public void send(){ System.out.println("this is sms sender"); } }
工廠類:
public classs SendFactory{ public Sender produce(String type){ if("mail".equals(type)){ return new MailSender(); }else if("sms".equals(type)){ return new SmsSender(); }else{ System.out.println("please input the correct type!"); return null; } }
public static void main(String[] args){
SendFactory factory=new SendFactory();
Sender sender = factory.produce("sms");
sender.Send();
} }
輸出:this is sms Sender!
b.多個工廠方法:對普通工廠進行了改進,在普通工廠方法模式中,若是傳遞的字符串出錯,則不能正確的建立對象,而多個工廠方法 提供多個工廠方法建立對象。
只需改動下工廠類:
public class SendFactory{ public Sender produceMail(){ return new MailSender(); } public Sender produceSms(){ return new SmsSender(); } public void static main(String[] args){ Sender mailSender =new SendFactory().produceMail(); } }
c.靜態工廠方法:將上面工廠方法模式裏的方法寫爲靜態方法,可經過類名+.直接調用。
工廠方法模式小結:結合a,b,c三種工廠方法模式,第c種發揮了前兩種的優點,摒棄了劣勢,最適合大多數狀況下使用。
2.抽象工廠模式:工廠方法模式有一個缺陷,若是想拓展程序,必須對工廠類進行修改,這違背了開閉原則。如何解決?用抽象工廠模式,建立多個工廠類,一旦須要加新功能,直接增長新的工廠類,就不須要修改以前寫好的工廠類代碼了。
抽象工廠接口:
public interface Provider{ public Sender produce(); }
原有的工廠類修改成兩個工廠類:
public class SendSmsFactory implements Provider{ @Override public Sender produce(){ return new SmsSender(); } }
public class SendMailFactory implements Provider{ @Override public Sender produce(){ return new MailSender(); } }
相應測試程序:
public class Test{ public void static main(String[] args){ Provider provider=new SendMailFactory(); Sender mailSender=provider.produce(); mailSender.send(); } }
3.單例模式:單例對象能保證在一jvm,只有一個實例存在。好處:某些類建立比較繁瑣,對於一些大型的對象,能夠節省開銷;省去了new操做符,下降了系統內存的使用頻率,減輕GC壓力;某些核心類,若是能夠建立多個,系統就徹底亂了。
單例類:
public class Singleton{ //私有靜態實例,防止被引用,此處賦值爲空,爲了實現延遲加載。 private static Singleton instance=null; //私有構造函數,防止外部直接new 實例化. private Singleton(){ } //靜態工廠方法,建立實例 public static Singleton getInstance(){ if(instance==null){ instance=new Singleton(); } return instance; }
//若是該對象被用於序列化,能夠保證對象在序列化先後保持一致
public Object readResolve(){
return instance;
} }
http://www.cnblogs.com/maowang1991/archive/2013/04/15/3023236.html
儘管這樣,仍是沒法保證安全,在多線程環境下確定會出問題的。咱們首先會想到對getInstance方法加synchronized關鍵字:
public static synchronized Singleton getInstance(){ if(instance==null){ instance=new Singleton(); } return instance; }
這樣時彷佛解決了問題,