策略模式
定義:定義一組算法,將每個(gè)算法都封裝起來(lái)霸奕,并且使它們之間可以互換溜宽。
應(yīng)用場(chǎng)景:
1.多個(gè)類只有在算法或行為上稍有不同的場(chǎng)景。
2.算法需要自由切換的場(chǎng)景质帅。
3.需要屏蔽算法規(guī)則的場(chǎng)景适揉。
角色:
Context封裝角色:屏蔽高層模塊對(duì)策略、算法的直接訪問(wèn)临梗,封裝可能存在的變化涡扼。
Strategy抽象策略角色:策略稼跳、算法家族的抽象盟庞,通常為接口,定義每個(gè)策略或算法必須具有的方法和屬性汤善。
ConcreteStrategy具體策略角色:實(shí)現(xiàn)抽象策略中的操作什猖,該類含有具體的算法。
實(shí)現(xiàn):
public class Price {
private int type;
public static final int TYPE_Primary = 1; //普通會(huì)員
public static final int TYPE_Intermediate = 2; //中級(jí)會(huì)員
public static final int TYPE_Advanced = 3; //高級(jí)會(huì)員
public void setType(int type){
this.type = type;
}
/**
* 計(jì)算圖書的價(jià)格
*/
public double quote(double booksPrice){
if(type == TYPE_Primary){
System.out.println("對(duì)于初級(jí)會(huì)員的沒(méi)有折扣");
return booksPrice;
} else if(type == TYPE_Intermediate){
System.out.println("對(duì)于中級(jí)會(huì)員的折扣為10%");
return booksPrice * 0.9;
} else if(type == TYPE_Advanced){
System.out.println("對(duì)于高級(jí)會(huì)員的折扣為20%");
return booksPrice * 0.8;
} else {
System.out.println("這是啥红淡?不狮??");
return -1;
}
}
}
策略模式實(shí)現(xiàn):
public interface MemberStrategy {
/**
* 計(jì)算圖書的價(jià)格
* @param booksPrice 圖書的原價(jià)
* @return 計(jì)算出打折后的價(jià)格
*/
public double calcPrice(double booksPrice);
}
public class PrimaryMemberStrategy implements MemberStrategy {
@Override
public double calcPrice(double booksPrice) {
System.out.println("對(duì)于初級(jí)會(huì)員的沒(méi)有折扣");
return booksPrice;
}
}
public class IntermediateMemberStrategy implements MemberStrategy {
@Override
public double calcPrice(double booksPrice) {
System.out.println("對(duì)于中級(jí)會(huì)員的折扣為10%");
return booksPrice * 0.9;
}
}
public class AdvancedMemberStrategy implements MemberStrategy {
@Override
public double calcPrice(double booksPrice) {
System.out.println("對(duì)于高級(jí)會(huì)員的折扣為20%");
return booksPrice * 0.8;
}
}
public class Price {
//持有一個(gè)具體的策略對(duì)象
private MemberStrategy strategy;
public setMemberStrategy(MemberStrategy strategy){
this.strategy = strategy;
}
/**
* 計(jì)算圖書的價(jià)格
*/
public double quote(double booksPrice){
return this.strategy.calcPrice(booksPrice);
}
}
策略模式的優(yōu)點(diǎn):
算法可以自由切換
避免使用多重條件判斷
擴(kuò)展性良好
策略模式的缺點(diǎn):
策略類數(shù)量增多
所有的策略類都需要對(duì)外暴露
狀態(tài)模式
定義:當(dāng)一個(gè)對(duì)象內(nèi)在狀態(tài)改變時(shí)允許其改變行為在旱,這個(gè)對(duì)象看起來(lái)像改變了其類摇零。
應(yīng)用場(chǎng)景:
1.行為隨狀態(tài)改變而改變的場(chǎng)景。
2.條件桶蝎、分支判斷語(yǔ)句的替代者驻仅。
角色:
State抽象狀態(tài)角色:接口或抽象類,負(fù)責(zé)對(duì)象狀態(tài)定義登渣,并且封裝環(huán)境角色以實(shí)現(xiàn)狀態(tài)切換噪服。
ConcreteState具體狀態(tài)角色:本狀態(tài)下要做的事情。
Context環(huán)境角色:定義客戶端需要的接口胜茧,并且負(fù)責(zé)具體狀態(tài)的切換粘优。
public interface MemberState {
/**
* 計(jì)算圖書的價(jià)格
* @param booksPrice 圖書的原價(jià)
* @return 計(jì)算出打折后的價(jià)格
*/
public void buyBook(double booksPrice);
}
public class PrimaryMemberState implements MemberState {
@Override
public void buyBook(double booksPrice) {
System.out.println("對(duì)于初級(jí)會(huì)員的沒(méi)有折扣" + booksPrice);
}
}
public class IntermediateMemberState implements MemberState {
@Override
public void buyBook(double booksPrice) {
System.out.println("對(duì)于中級(jí)會(huì)員的折扣為10%" + booksPrice * 0.9);
}
}
public class AdvancedMemberState implements MemberState {
@Override
public void buyBook(double booksPrice) {
System.out.println("對(duì)于高級(jí)會(huì)員的折扣為20%"+ booksPrice * 0.8);
}
}
public class Person {
//持有一個(gè)具體的策略對(duì)象
private MemberState state;
public setMemberStrategy(MemberState state){
this.state = state;
}
/**
* 買一本書
*/
public void buyBook(double booksPrice){
this.state.buyBook(booksPrice);
}
}
策略模式vs狀態(tài)模式:
問(wèn)題的重點(diǎn)是業(yè)務(wù)關(guān)注的是什么,是狀態(tài)還是工作邏輯呻顽?找準(zhǔn)了業(yè)務(wù)的焦點(diǎn)雹顺,才能選擇一個(gè)好的設(shè)計(jì)模式。
解決問(wèn)題的重點(diǎn)不同:
策略模式旨在解決內(nèi)部算法如何改變的問(wèn)題廊遍,也就是將內(nèi)部算法的改變對(duì)外界的影響降低到最小无拗,它保證的是算法可以自由地切換;
而狀態(tài)模式旨在解決內(nèi)在狀態(tài)的改變而引起行為改變的問(wèn)題昧碉,它的出發(fā)點(diǎn)是事物的狀態(tài)英染,封裝狀態(tài)而暴露行為揽惹,一個(gè)對(duì)象的狀態(tài)改變,從外界來(lái)看就好像是行為改變四康。