定義
策略模式定義了一系列的算法供鸠,并將每一個(gè)算法封裝起來(lái),而且使它們還可以相互替換陨闹,策略模式讓算法獨(dú)立于使用它的客戶(hù)而獨(dú)立變化楞捂。
使用場(chǎng)景
- 針對(duì)同一類(lèi)型問(wèn)題的多種處理方式,僅僅是具體行為有差別時(shí)趋厉。
- 需要安全的封裝多種同一類(lèi)型的操作時(shí)寨闹。
- 出現(xiàn)同一抽象類(lèi)有多個(gè)子類(lèi),而又需要使用if - else或者switch - case 來(lái)選擇具體子類(lèi)時(shí)君账。
優(yōu)點(diǎn)
- 結(jié)構(gòu)清晰明了繁堡、使用簡(jiǎn)單直觀。
- 耦合度相對(duì)而言較低,擴(kuò)展方便
- 操作封裝也更為徹底椭蹄,數(shù)據(jù)更為安全闻牡。
- 隨著策略的增加,子類(lèi)也會(huì)變得繁多绳矩。
關(guān)鍵類(lèi)
- 策略的頂級(jí)接口罩润,策略的具體實(shí)現(xiàn)類(lèi),策略的上下文環(huán)境類(lèi)
在Android 源碼的應(yīng)用
- Android 動(dòng)畫(huà)插值器翼馆。
好了割以,又是一對(duì)概念,優(yōu)缺點(diǎn)应媚,場(chǎng)景等官方的話拳球,但是往往定義也是很重要的,下面繼續(xù)生活場(chǎng)景珍特。
生活實(shí)例
我們繼續(xù)說(shuō)王二麻子的故事祝峻,上次土地登記錯(cuò)誤,提交了報(bào)告扎筒,本身想的會(huì)解決掉莱找,但是由于各種原因,還辦成這件事嗜桌,所以王二麻子焦急了奥溺,打算去另一個(gè)城市找一下自己的朋友尋求幫助,由于距離比較遠(yuǎn)骨宠,王二麻子向的怎么去浮定,有三種辦法目前,坐飛機(jī)层亿,坐火車(chē)桦卒,坐汽車(chē),好匿又,我們現(xiàn)在就設(shè)計(jì)一下代碼方灾,送王二麻子去見(jiàn)朋友。
封裝出行方式類(lèi):
public class Traffic {
public static void air(){ //飛機(jī)
System.out.print("800");
}
public static void train(){ //火車(chē)
System.out.print("300");
}
public static void bus(){ //長(zhǎng)途汽車(chē)
System.out.print("400");
}
}
測(cè)試類(lèi)
public class MyClass {
public static void main(String[] args) {
Traffic.air();
Traffic.train();
Traffic.bus();
}
}
這里我們很簡(jiǎn)單的直接調(diào)用Traffic
類(lèi)的靜態(tài)方法就可以讓王二麻子選擇出行方式碌更,這樣看起來(lái)很好很正常裕偿,但是也明顯有弊端,假如王二麻子想要坐私家車(chē)出行痛单,這個(gè)就得再向traffic
類(lèi)里面加一個(gè)靜態(tài)方法嘿棘,這樣隨著出行的方式的增加我們這個(gè)類(lèi)一只在修改,這樣違反了開(kāi)閉原則旭绒,而且類(lèi)變的越來(lái)越大鸟妙,變得難以維護(hù)后期焦人。所以我們就得考慮用一個(gè)套路-策略套路。
接下來(lái)我們用策略套路來(lái)給王二麻子設(shè)計(jì)出行路線:
所有方式的頂級(jí)接口
public interface CommonTraffic {
void getPrice();
}
飛機(jī)類(lèi)
public class Air implements CommonTraffic {
@Override
public void getPrice() {
System.out.print(800);
}
}
火車(chē)類(lèi)
public class Train implements CommonTraffic {
@Override
public void getPrice() {
System.out.print(300);
}
}
汽車(chē)類(lèi)
public class Bus implements CommonTraffic {
@Override
public void getPrice() {
System.out.print(400);
}
}
王二麻子直接調(diào)用的交通類(lèi)
public class Traffic {
private CommonTraffic traffic;
public void getPrice() {
traffic.getPrice();
}
public void setTraffic(CommonTraffic traffic) {
this.traffic = traffic;
}
}
這個(gè)中間類(lèi)很重要圆仔,它是策略模式的關(guān)鍵。
測(cè)試類(lèi)
public class MyClass {
public static void main(String[] args) {
Traffic traffic = new Traffic(); //創(chuàng)建交通類(lèi)
Air air = new Air(); //選擇要出行的方式
traffic.setTraffic(air); //設(shè)置給交通類(lèi)
traffic.getPrice(); //獲取出行價(jià)格
}
}
接下來(lái)我們?cè)倏赐醵樽哟蛩闼郊臆?chē)出行蔫劣,那么坪郭,只需要?jiǎng)?chuàng)建一個(gè)私家車(chē)類(lèi),然后設(shè)置給traffic
就可以脉幢。這樣很好的滿足了開(kāi)閉原則歪沃,架構(gòu)上很清晰,不會(huì)因?yàn)樾薷哪骋环N出行方式而可能影響其他類(lèi),高度解耦嫌松,這就是策略模式的好處沪曙。
下面我們?cè)倥e一個(gè)Android開(kāi)發(fā)中遇到的使用策略模式的情況:
比如我們自定義了一個(gè)View:
public class CustomView extends View {
private ICustomView customBean;
public CustomView(Context context) {
super(context);
}
public CustomView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public CustomView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
customBean.getViewName();
customBean.getViewAge();
customBean.getViewAddress();
customBean.getViewMotto();
}
public void setData(ICustomView bean){
this.customBean = bean;
}
}
實(shí)體類(lèi):
interface ICustomView {
public String getViewName();
public int getViewAge();
public String getViewAddress();
public String getViewMotto();
//...
}
上面我們自定義了一個(gè)view,數(shù)據(jù)就是通過(guò)public void setData(ICustomView bean)
這個(gè)方法設(shè)置萎羔,而ICustomView
這個(gè)接口里面有很多字段獲取方法液走,那么我們可能會(huì)在很多地方都用到這個(gè)自定義view,但是服務(wù)器給的字段名字不可能一樣,那么怎么辦?我們用策略套路贾陷,讓所有的使用自定義view的數(shù)據(jù)類(lèi)都繼承一個(gè)公共的接口缘眶,這個(gè)接口提供返回統(tǒng)一數(shù)據(jù)的方法,這樣就實(shí)現(xiàn)了復(fù)用髓废,這其實(shí)也是策略模式的一種巷懈。
總結(jié)
第二篇就這樣結(jié)束了,都是根據(jù)自己的理解和碰到的問(wèn)題寫(xiě)的慌洪,定義優(yōu)缺點(diǎn)已經(jīng)總結(jié)到上面顶燕,看完例子大家再去看一下定義這些東西,可能會(huì)理解很多冈爹。