策略模式定義是:定義算法族,分別封裝起來,讓它們之間可以互相替換,算法的變化獨立於使用算法的客戶。
我們來模擬一種情形來理解這句話。有一羣鴨子,有各種顏色的鴨,他們有的會飛,有的不會飛,飛的姿態也更不相同。此時如果在每隻鴨子裏分別定義飛的姿態,那有成千上萬中鴨子的時候就會累死。這時我們考慮使用設計模式來實現下它。
- 設計原則中第一條:找出應用中可能需要變化之處,把它們獨立出來。當然這裏我們獨立的就是會變化的飛行爲。
- 設計模式第二條:針對接口編程,而不是針對實現編程。所以到這裏我們寫出如下飛的代碼:
public interface FlyBehavior {
public void fly();
}
定義了接口類,再定義實現類,會簡單,只定義會飛和不會飛行爲:
public class NoFly implements FlyBehavior {
@Override
public void fly() {
// TODO Auto-generated method stub
System.out.println("this duck can not fly");
}
}
public class CanFly implements FlyBehavior{
@Override
public void fly() {
// TODO Auto-generated method stub
System.out.println("this duck can fly");
}
}
以上就是針對==接口編程==。
- 設計原則第三條:多用組合,少用繼承。那我們也來運用下。定義鴨子的抽象類:
public abstract class Duck {
FlyBehavior flyBehavior;
public abstract void disply();
public void performFly(){
flyBehavior.fly();
}
public FlyBehavior getFlyBehavior() {
return flyBehavior;
}
public void setFlyBehavior(FlyBehavior flyBehavior) {
this.flyBehavior = flyBehavior;
}
}
其中它有一個FlyBehavior對象,組合了飛的行爲。
好了,接下來就是實體鴨子,只要繼承超類就可以了。
public class RedDuck extends Duck{
public RedDuck() {
// TODO Auto-generated constructor stub
flyBehavior = new NoFly();//默認不會飛
}
@Override
public void disply() {
// TODO Auto-generated method stub
System.out.println("the color is red");
}
}
紅鴨不會飛,再來一隻黑鴨會飛:
public class BlackDuck extends Duck{
public BlackDuck() {
// TODO Auto-generated constructor stub
flyBehavior = new CanFly();//默認不會飛
}
@Override
public void disply() {
// TODO Auto-generated method stub
System.out.println("the color is black");
}
}
public class Main {
public static void main(String[] args){
Duck duck = new RedDuck();
duck.performFly();
duck.disply();
duck.setFlyBehavior(new CanFly());
duck.performFly();
System.out.println("-----------------");
Duck duck2 = new BlackDuck();
duck2.performFly();
duck2.disply();
duck2.setFlyBehavior(new NoFly());
duck2.performFly();
}
}
好處己經非常明顯了,要什麼飛行行爲只要在運行時進行替換就可以了。這種模式的好處:實現不會被綁死在子類中,使用接口,可以運行時替換。看上它的UML圖:
[設計模式]Strategy策略模式