四、设计模式——策略模式
2019獨角獸企業重金招聘Python工程師標準>>>
面向對象的設計方案
產品狗今天跟你說,要做一個“模擬鴨子游戲”,需求如下:
鴨子有共同的功能,比如游泳和叫。
鴨子也有不同的功能,比如有綠頭鴨和紅頭鴨。
所以想到了通過使用OO的方式,將共同的功能放在抽象類Duck中,而不同的用abstract修飾供子類實現。
public?abstract?class?Duck?{public?Duck()?{}public?void?Quack()?{System.out.println("~~gaga~~");}public?abstract?void?display();//不同樣子的鴨子,有不同的實現public?void?swim()?{System.out.println("~~im?swim~~");} } public?class?GreenHeadDuck?extends?Duck?{//綠頭鴨@Overridepublic?void?display()?{System.out.println("**GreenHead**");} } public?class?RedHeadDuck?extends?Duck?{//紅頭鴨@Overridepublic?void?display()?{System.out.println("**RedHead**");} }通過面向對象的思想,我們實現了復用,完成了需求。
新需求
看看這種設計在增加新功能的時候,其擴展性如何。
新需求:添加會飛的鴨子
public?abstract?class?Duck?{//...略...public?void?Fly()?{System.out.println("~~im?fly~~");} }如果在超類中添加這段代碼,那么問題馬上就來了,超類中添加的方法對所有之類都生效,而不是所有的鴨子都需要這個功能。
public?class?GreenHeadDuck?extends?Duck?{//...略...public?void?Fly()?{System.out.println("~~no?fly~~");} }那我們可以覆蓋掉不會飛的鴨子的fly方法,不就可以了嗎~~~
問題又來了,如果有10種不會飛的鴨子,豈不是要重復做10次重復性的工作?
那可不可以把超類中的fly方法弄成abstract呢?
這樣所有的之類不就都要實現fly方法嗎~如果50種鴨子,那就需要實現50次!
如果又有新需求,比如石頭鴨子,既不會飛也不會叫 ,如何實現? +_+
看來上述都不是很好的設計方案。
思路
分析軟件設計需要考慮兩方面的問題
1)分析項目變化和不變的部分,對于變化的部分,抽象成接口+實現;
2)找到那些功能會根據新需求而變化。
這個模擬鴨子的游戲中,鴨子的叫聲和飛行方式會變。
策略模式實現
對飛行和叫分別設計接口,對于不同的叫聲和飛行再通過實現的方式完成。
public?interface?FlyBehavior?{void?fly(); } public interface?QuackBehavior?{void?quack(); }這樣新增行為變得很簡單,只需要實現相同的接口即可。
在鴨子超類中,通過組合抽象的飛行和抽象的叫聲,具體的叫和飛交給之類補充。
import?com.java.hexter.stimulateduck.flybehavior.FlyBehavior; import?com.java.hexter.stimulateduck.quackbehavior.QuackBehavior;public?abstract?class?Duck?{FlyBehavior?mFlyBehavior;QuackBehavior?mQuackBehavior;public?Duck()?{}public?void?Fly()?{mFlyBehavior.fly();}public?void?Quack()?{mQuackBehavior.quack();}public?abstract?void?display();public?void?SetQuackBehavoir(QuackBehavior?qb)?{mQuackBehavior?=?qb;}public?void?SetFlyBehavoir(FlyBehavior?fb)?{mFlyBehavior?=?fb;}public?void?swim()?{System.out.println("~~im?swim~~");} }看到沒有,抽象超類中沒有任何具體的實現類耦合,而是通過接口調用。
里面的fly還是quack函數,都是根據之類mFlyBehavior和mQuackBehavior的不同而不同。
看看綠頭鴨以及紅頭鴨的實現過程。
public?class?GreenHeadDuck?extends?Duck?{public?GreenHeadDuck()?{mFlyBehavior?=?new?GoodFlyBehavior();mQuackBehavior?=?new?GaGaQuackBehavior();}@Overridepublic?void?display()?{System.out.println("**GreenHead**");} }public?class?RedHeadDuck?extends?Duck?{public?RedHeadDuck()?{mFlyBehavior?=?new?BadFlyBehavior();mQuackBehavior?=?new?GeGeQuackBehavior();}@Overridepublic?void?display()?{System.out.println("**RedHead**");} }很強大,又木有~~~ 腦洞打開的趕腳
策略模式:
行為抽象成接口,并且實現算法族,在超類中放行為接口對象,子類里具體設置行為對象。
原則是分離變化部分,封裝接口,基于接口編程各種功能,讓行為的實現能單獨變化。
轉載于:https://my.oschina.net/gaohongtian/blog/492113
總結
以上是生活随笔為你收集整理的四、设计模式——策略模式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 为Jfinal-weixin SDK添加
- 下一篇: 重在参与吗。。。。。。。。