簡(jiǎn)述
設(shè)計(jì)模式是一套被反復(fù)使用、多數(shù)人知曉的、經(jīng)過(guò)分類編目的、代碼設(shè)計(jì)經(jīng)驗(yàn)的總結(jié)。
使得設(shè)計(jì)是為了可重用代碼、讓代碼更容易被他人理解、保證代碼可靠性。
設(shè)計(jì)模式于己于他(他人)于它(系統(tǒng))都是多贏的,設(shè)計(jì)模式使代碼編制真正工程化。
設(shè)計(jì)模式是軟件工程的基石脈絡(luò),如同大廈的結(jié)構(gòu)一樣。
一、設(shè)計(jì)模式的六大原則
1.單一職責(zé)原則
2.里氏替換原則
任何基類可以出現(xiàn)的地方,子類一定可以出現(xiàn)。
3.依賴倒轉(zhuǎn)原則
面向接口編程,依賴于抽象而不依賴具體。
4.接口隔離原則
一個(gè)類對(duì)另一個(gè)類的依賴應(yīng)該建立在最小的接口上。
5.迪米特法則
一個(gè)對(duì)象應(yīng)當(dāng)對(duì)其他對(duì)象有盡可能少的了解,不和陌生人說(shuō)話。
6.合成復(fù)用原則
原則是盡可能收下使用合成/聚合的方式,而不是使用繼承
總原則:開(kāi)閉原則
對(duì)擴(kuò)展開(kāi)發(fā),對(duì)修改關(guān)閉。
二、23種設(shè)計(jì)模式
1.單例模式
在系統(tǒng)中,為了節(jié)省內(nèi)存資源、保證數(shù)據(jù)內(nèi)容一致性,對(duì)某些類要求只能創(chuàng)建一個(gè)實(shí)例。
懶漢式單例
public class Singleton{
private volatile static Singleton singleton;
private Singleton(){}
public synchronized static Single newInstance(){
if(singleton == null){
singleton = new Singleton();
}
return singleton;
}
}
當(dāng)類被加載的時(shí)候,靜態(tài)變量instance會(huì)被初始化,
此時(shí)類的私有構(gòu)造函數(shù)會(huì)被調(diào)用,單例類唯一實(shí)例將被創(chuàng)建。
餓漢單例
public class Singleton{
private static Singleton singleton = new Singleton();
private singleton(){}
public static Singleton newInstance(){
return singleton;
}
}
在單例對(duì)象聲明的時(shí)候就直接初始化對(duì)象,可以避免多線程問(wèn)題,
但是如果對(duì)象初始化比較復(fù)雜,會(huì)導(dǎo)致程序初始化緩慢。
2.三種工廠模式
a.靜態(tài)工廠:用來(lái)生產(chǎn)一等級(jí)結(jié)構(gòu)中的任意產(chǎn)品,產(chǎn)品的
創(chuàng)建是由你傳入?yún)?shù)決定的。
b.工廠方法:用來(lái)生產(chǎn)一等級(jí)結(jié)構(gòu)中的固定產(chǎn)品,一個(gè)工廠
只能生產(chǎn)一個(gè)固定的產(chǎn)品。
c.抽象工廠:用來(lái)生產(chǎn)不同產(chǎn)品族的全部產(chǎn)品,一個(gè)工廠可以
生產(chǎn)跟該產(chǎn)品相關(guān)的一系列產(chǎn)品。
1>.簡(jiǎn)單工廠模式
a.簡(jiǎn)單工廠模式也叫靜態(tài)工廠模式,一般使用靜態(tài)方法,
通過(guò)接收的參數(shù)的不同的對(duì)象的不同來(lái)返回不同的對(duì)象實(shí)例。
b.對(duì)于新功能,需要修改代碼,擴(kuò)展性差。
2>.工廠方法模式
a.工廠方法模式完全滿足OCP,弊端是每次擴(kuò)展都會(huì)增加新的類。
b.工廠方法模式和簡(jiǎn)單工廠模式最大的不同在于,簡(jiǎn)單工廠模式只有
一個(gè)工廠類,工廠方法模式有一組實(shí)現(xiàn)了相同接口的工廠類。
3>.抽象工廠模式
a.抽象工廠模式提供了一種方式,可以將同一產(chǎn)品族的單獨(dú)的工廠封裝起來(lái)。
b.比如生產(chǎn)手機(jī),還需要生產(chǎn)相應(yīng)的充電器,手機(jī)和充電器就相當(dāng)于產(chǎn)
品族,手機(jī)可以生產(chǎn)蘋(píng)果手機(jī)、小米手機(jī)等,充電器可以生產(chǎn)蘋(píng)果
充電器、小米充電器等。
3.代理模式
代理模式的定義:
代理模式給某一個(gè)對(duì)象提供一個(gè)代理對(duì)象,并由代理對(duì)象控制對(duì)原對(duì)象的引用。
舉例說(shuō)明:
某人通過(guò)房屋中介的方式租房,房屋中介就是代理。
a.應(yīng)用場(chǎng)景:
遠(yuǎn)程代理:為位于兩個(gè)不同地址空間對(duì)象的訪問(wèn)提供了一種實(shí)現(xiàn)機(jī)制,
可以將一些消耗資源較多的對(duì)象和操作移至性能更好的計(jì)算器上,
提高系統(tǒng)的整體運(yùn)行效率。
虛擬代理:通過(guò)一個(gè)消耗資源較少的對(duì)象來(lái)代表一個(gè)消耗資源較多的對(duì)象,
可以在一定程度上節(jié)省系統(tǒng)的開(kāi)銷。
緩存代理:為某一個(gè)操作的結(jié)果提供臨時(shí)的緩存存儲(chǔ)空間,以便在后續(xù)使
用中能夠共享這些結(jié)果,優(yōu)化系統(tǒng)性能。
保護(hù)代理:可以控制對(duì)一個(gè)對(duì)象的訪問(wèn)權(quán)限,為不同用戶提供不同級(jí)別的使用權(quán)限。
智能引用:要為一個(gè)對(duì)象的訪問(wèn)(引用)提供一些額外的操作
b.靜態(tài)代理
寫(xiě)死了在代理對(duì)象中執(zhí)行這個(gè)方法前后執(zhí)行添加功能的形式,每次要在接口添加
一個(gè)新方法,則需要在目標(biāo)對(duì)象中實(shí)現(xiàn)這個(gè)方法,并且在代理對(duì)象中實(shí)現(xiàn)相應(yīng)的代理方法。
//1.創(chuàng)建租房接口
public interface IRentHouse{
void rentHouse();
}
//2.創(chuàng)建客戶,實(shí)現(xiàn)租房接口
public class Customer implements IRentHouse{
private String rentType;
public void setRentType(String rentType){
this.rentType = rentType;
}
public String getRentType(){
return rentType;
}
@Override
public void rentHouse(){
Log.i("Customer","租一個(gè)"+rentType+"房子");
}
}
//3.房屋中介
public class RentHouseProxy implements IRentHouse{
private Customer customer; //客戶
public RentHouseProxy(Customer customer){
this.customer = customer;
}
@Override
public void rentHouse(){
customer.rentHouse();
}
}
c.動(dòng)態(tài)代理
例如:王二狗租房,沒(méi)有租房前,不確定是哪個(gè)中介客服,而是在租房的時(shí)候才確定
是哪位帶他去看房。映射到編程2領(lǐng)域?yàn)檫@個(gè)關(guān)系是在運(yùn)行時(shí)確定的。
jdk動(dòng)態(tài)代理
JDK的動(dòng)態(tài)代理實(shí)現(xiàn)方法是依賴于接口,通過(guò)Proxy類產(chǎn)生的代理對(duì)象調(diào)用被代理
對(duì)象的操作,又被分發(fā)給InvocationHandler接口的invoke方法具體執(zhí)行。
cgLib動(dòng)態(tài)代理
能對(duì)沒(méi)有實(shí)現(xiàn)接口的類做動(dòng)態(tài)代理,
動(dòng)態(tài)生成一個(gè)要代理類的子類,子類重寫(xiě)要代理的類的所有不是final的方法。
在子類中采用方法攔截的技術(shù)攔截所有父類方法的調(diào)用,順勢(shì)織入橫切邏輯。
MethodInterceptor接口方法攔截