1.模擬鴨子項目
/**
* 鴨子
*/
public abstract class Duck {
public Duck(){
}
public void quack(){
System.out.println("~gagaga~");
}
public abstract void display();
public void swim(){
System.out.println("~im swim~");
}
}
/**
* 綠頭鴨子
*/
class GreenHeaderDuck extends Duck{
@Override
public void display() {
System.out.println("我是綠頭鴨");
}
public static void main(String[] args) {
Duck duck = new GreenHeadDuck();
duck.display(); //
duck.quack(); //鴨子叫聲
duck.swim();//鴨子游泳
}
}
正常鴨子是會嘎嘎叫,和會游泳的。這裏沒什麼問題。
2.項目新需求
突然來了一個新需求,說要加一種會飛的鴨子,這裏區別有的鴨子會飛,有的鴨子不會飛。
3.用OO原則解決新需求的不足
如果現在你在超類Duck.java中加入方法:
public void fly(){
System.out.println("~im fly~");
}
那麼當前出現問題,不會飛的鴨子也會出現‘im fly’,你可能由這樣寫,把fly(){}改爲
public abstract void fly();
那麼所以的鴨子子類都需要實現當前方法。
會飛的鴨子:
@Override
public void fly() {
System.out.println("我會飛");
}
不會飛的
@Override
public void fly() {
System.out.println("我不會飛");
}
這樣影響太大,所以的子類都需要實現 ,勞動量太大
4.用策略模式來新需求解決
1.分析項目變化與不變化部分,提取變化部分,抽象成接口+實現
2.鴨子哪些功能會根據新需求變化的?比如上面的 ’飛行‘
public interface FlyBehavior{
void fly();
}
實現飛行:
public class MyFlyBehavior implements FlyBehavior {
public void fly() {
System.out.println("我會飛");
}
}
好處:新增行爲簡單,行爲類更好的複用
5.重新設計模擬鴨子項目
/**
* 鴨子
*/
public abstract class Duck {
FlyBehavior flyBehavior;
public Duck(){
}
/**
* 重新定義fly
*/
public void Fly(){
flyBehavior.fly();
}
public void quack(){
System.out.println("~gagaga~");
}
public abstract void display();
public void swim(){
System.out.println("~im swim~");
}
}
public class GreenHeadDuck extends Duck {
public GreenHeadDuck(){
flyBehavior = new MyFlyBehavior();
}
@Override
public void display() {
System.out.println("我是綠頭鴨");
}
}
6.總結策略模式定義
封裝行爲爲接口,超類裏放行爲接口對象,在子類裏具體設定行爲對象,
原則:分離變化部分,封裝接口,基於接口編程各種功能,此模式讓行爲
算法的變化獨立於算法的使用者