第1章:策略模式
阿新 • • 發佈:2019-05-09
rate 部分 方案 pattern 應用場景 繼承 方法 rmq play
1 策略模式
策略模式定義了算法族分別封裝起來,讓他們之間可以相互替換(實現接口),此模式讓算法的變化獨立於使用算法的客戶(組合+委托)
1.1 應用場景
需要方法的實現獨立於客戶端代碼,即保證客戶端代碼不變前提下,方法具體執行內容可以任意更換
Duck mallardDuck = new MallardDuck();
//下方代碼後,該語句的調用產生不同的結果,即算法間的相互替換
mallardDuck.setFlyBehavior(new FlyNoWay());
mallardDuck.performFly();
1.2 錯誤解決方案
1.2.1 父類中直接增加方法
package strategy.pattern; public abstract class Duck1 { //組合解決的問題 //1.所有Duck1中,不會飛或不是quack這麽叫的鴨子,都需要重寫下面方法,這樣重復代碼太多,不利於維護 //策略模式解決的問題 //2.客戶端調用同一個類型的子類對象的該方法結果是固定的,例如創建一個Duck1子類,該對象無法完成一會可以飛,一會不能飛 public void fly(){ System.out.println("I can fly"); } public void quack(){ System.out.println("quack"); } }
1.2.2 不同子類實現不同包含方法的接口,並重寫該方法
FlyBehavior接口中定義抽象方法fly,所有鴨子實現該接口,並重寫fly方法,與上面缺點相同
1.3 解決思路
1.3.1 分開變化和不會變化的部分
==設計原則:找出應用中可能需要變化之處,把它們獨立出來,不要和那些不需要變化的代碼混在一起==
- 分析該問題中,fly與quack對於不同的鴨子子類,行為是不同的,因此應該將該方法的具體實現與鴨子類本身分離開
- Duck2
package strategy.pattern; public abstract class Duck2 { Quack quack = new Quack(); FlyWithWings flyWithWings = new FlyWithWings(); public void fly(){ //具體的實現在Quack和FlyWithWings中定義,達到了和Duck2及其子類的分離 flyWithWings.fly(); } public void quack(){ quack.quack(); } }
1.3.2 面向接口編程
==設計原則:針對接口編程,而不是針對實現編程==
==設計原則:多用組合少用繼承==
- 之前無法動態地指定鴨子子類的行為,也無法為特定鴨子子類指定特定行為
- Duck3
package strategy.pattern; public abstract class Duck3 { //1.QuackBehavior、FlyBehavior為接口,此處為面向接口編程 //使用組合解決了繼承帶來的代碼重復問題 QuackBehavior quack; FlyBehavior flyWithWings; public void fly(){ //執行的是flyWithWings變量指向的真正的對象的fly方法 flyWithWings.fly(); } public void quack(){ quack.quack(); } //2.可以指定具體行為對應類,可以動態的指定鴨子子類的行為,也可以為特定鴨子子類指定特定行為 public void setQuack(QuackBehavior quack) { this.quack = quack; } public void setFlyWithWings(FlyBehavior flyWithWings) { this.flyWithWings = flyWithWings; } }
1.4 類圖
1.5 代碼
- FlyBehavior:接口
package strategy.pattern;
public interface FlyBehavior {
void fly();
}
- FlyNoWay:實現類
package strategy.pattern;
public class FlyNoWay implements FlyBehavior {
@Override
public void fly() {
System.out.println("I cant fly");
}
}
- FlyWithWings:實現類
package strategy.pattern;
public class FlyWithWings implements FlyBehavior {
@Override
public void fly() {
System.out.println("I'm flying");
}
}
- QuackBehavior:接口
package strategy.pattern;
public interface QuackBehavior {
void quack();
}
- Quack:實現類
package strategy.pattern;
public class Quack implements QuackBehavior{
@Override
public void quack() {
System.out.println("Quack");
}
}
- Squeak:實現類
package strategy.pattern;
public class Squeak implements QuackBehavior{
@Override
public void quack() {
System.out.println("Squeak");
}
}
- MuteQuack:實現類
package strategy.pattern;
public class MuteQuack implements QuackBehavior{
@Override
public void quack() {
System.out.println("Silence");
}
}
- Duck
package strategy.pattern;
public abstract class Duck {
//使用策略模式實現鴨子的各種行為,即鴨子的行為封裝在一組類中,可以輕易的擴充與改變
FlyBehavior flyBehavior;
QuackBehavior quackBehavior;
public abstract void display();
public void swim(){
System.out.println("All ducks float,even decoys");
}
public void performFly(){
flyBehavior.fly();
}
public void performQuack(){
quackBehavior.quack();
}
//提供兩個set方法,可以動態修改鴨子的行為
public void setFlyBehavior(FlyBehavior flyBehavior) {
this.flyBehavior = flyBehavior;
}
public void setQuackBehavior(QuackBehavior quackBehavior) {
this.quackBehavior = quackBehavior;
}
}
- MallardDuck:綠頭鴨,Duck的一個實現類
package strategy.pattern;
public class MallardDuck extends Duck{
@Override
public void display() {
System.out.println("I'm a real Mallard duck");
}
//初始化時,順便初始化綠頭鴨的所有行為
public MallardDuck(){
flyBehavior = new FlyWithWings();
quackBehavior = new Quack();
}
}
- MallarDuckSimulator:測試類
package strategy.pattern;
public class MallarDuckSimulator {
public static void main(String[] args) {
Duck mallardDuck = new MallardDuck();
mallardDuck.performFly();
mallardDuck.performQuack();
mallardDuck.setFlyBehavior(new FlyNoWay());
//前後同一個對象mallardDuck調用同一個方法performFly,打印的內容不同,即可以在運行時改變行為
mallardDuck.performFly();
}
}
第1章:策略模式