概述
在日常開發(fā)工作中,適當(dāng)?shù)氖褂靡恍┰O(shè)計(jì)模式,可以讓代碼擴(kuò)展性更強(qiáng),能更好地?fù)肀ё兓?,讓代碼更加優(yōu)雅。本文主要介紹設(shè)計(jì)模式中的策略模式,并附上測(cè)試示例 Demo 供大家參考。
定義
策略模式定義了一系列的算法,并將每一個(gè)算法封裝起來,而且使它們還可以相互替換。策略模式讓算法獨(dú)立于使用它的客戶而獨(dú)立變化。
個(gè)人理解
策略模式,針對(duì)那些動(dòng)作因?qū)ο蠖惖那闆r下,把每一個(gè)動(dòng)作都獨(dú)立封裝起來并實(shí)現(xiàn)同一個(gè)接口,通過組合的方式賦予對(duì)象相對(duì)應(yīng)的動(dòng)作,從而使得所有的動(dòng)作都可以相互替換。通過策略模式,可以達(dá)到在運(yùn)行時(shí)修改對(duì)象的具體動(dòng)作、對(duì)象和具體動(dòng)作之間解耦的效果。
設(shè)計(jì)原則
1)找出應(yīng)用中可能需要變化的地方,把它們獨(dú)立出來,不要和那些不需要變化的代碼混在一起;
2)面向接口編程,而不是面向?qū)崿F(xiàn)編程;
3)多用組合,少用繼承;
示例介紹
這里我以 CF 里面的背包為例子來描述策略模式(有可能 CF 背包的設(shè)計(jì)不是我講的這樣,這里只是舉例說明策略模式)。玩過 CF 的同學(xué)都知道,每個(gè)角色都有自己的背包,背包里面可以放主武器、副武器、投擲類武器等。而這幾類武器,又包含多種具體型號(hào)的武器,比如:主武器可以是狙擊步槍、沖鋒槍,副武器可以是普通手槍、左輪手槍,投擲類武器可以是手雷、煙霧彈、閃光彈等。為了能夠達(dá)到能夠隨時(shí)調(diào)整背包裝備的效果,可以采用策略模式。UML 圖如下:
從上面的 UML 可以看出,先定義一個(gè)主武器的接口類 IMainArms 和投擲類武器的接口類 IThrowArms,然后讓狙擊步槍類 SniperRifle 和 沖鋒槍類 SubmachineGun 都去實(shí)現(xiàn)主武器接口,讓手雷類 AntitankGrenade 、閃光彈類 FlashBomb 和 煙霧彈類 SmokeBomb 都去實(shí)現(xiàn)投擲類武器接口,接著再在背包類 Pack 中通過 IMainArms 和 IThrowArms 兩個(gè)接口聲明一個(gè)主武器變量和一個(gè)投擲類武器的變量。至此,在配置背包時(shí),就可以根據(jù)實(shí)際需要,往背包里面放不同的主武器和不同的投擲類武器,如果有新的主武器或者投擲類武器需要?jiǎng)?chuàng)建,則只需要在創(chuàng)建對(duì)應(yīng)的類時(shí),以相同的方式實(shí)現(xiàn)對(duì)應(yīng)的接口后,即可像原有的武器使用方式使用新的武器。
示例代碼
IMainArms 主武器接口
package strategy;public interface IMainArms { void fire(); void aim(); }
IThrowArms 投擲類武器接口
package strategy;public interface IThrowArms { void bomb(); }
SniperRifle 狙擊步槍類
package strategy;public class SniperRifle implements IMainArms { private int bulletNum; @Override public void fire() { if(this.bulletNum>0){ System.out.println("狙擊槍扣動(dòng)扳機(jī)..."); this.bulletNum = this.bulletNum - 1; } } @Override public void aim() { System.out.println("狙擊槍瞄準(zhǔn)..."); } public int getBulletNum() { return bulletNum; } public void setBulletNum(int bulletNum) { this.bulletNum = bulletNum; } }
SubmachineGun 沖鋒槍類
package strategy;public class SubmachineGun implements IMainArms { private int bulletNum; @Override public void fire() { if(this.bulletNum>0){ System.out.println("沖鋒槍扣動(dòng)扳機(jī)..."); this.bulletNum = this.bulletNum - 1; } } @Override public void aim() { System.out.println("沖鋒槍瞄準(zhǔn)..."); } public int getBulletNum() { return bulletNum; } public void setBulletNum(int bulletNum) { this.bulletNum = bulletNum; } }
AntitankGrenade 手雷類
package strategy;public class AntitankGrenade implements IThrowArms { private boolean isBomb; @Override public void bomb() { System.out.println("手雷爆炸..."); this.setBomb(true); } public boolean isBomb() { return isBomb; } public void setBomb(boolean isBomb) { this.isBomb = isBomb; } }
FlashBomb 閃光彈類
package strategy;public class FlashBomb implements IThrowArms { private boolean isBomb; @Override public void bomb() { System.out.println("閃光彈爆炸..."); this.setBomb(true); } public boolean isBomb() { return isBomb; } public void setBomb(boolean isBomb) { this.isBomb = isBomb; } }
SmokeBomb 煙霧彈類
package strategy;public class SmokeBomb implements IThrowArms { private boolean isBomb; @Override public void bomb() { System.out.println("煙霧彈爆炸..."); this.setBomb(true); } public boolean isBomb() { return isBomb; } public void setBomb(boolean isBomb) { this.isBomb = isBomb; } }
MainTest 測(cè)試類
package test;import strategy.AntitankGrenade;import strategy.FlashBomb;import strategy.Pack;import strategy.SniperRifle;import strategy.SubmachineGun;public class MainTest { public static void main(String[] args) { SniperRifle sniperRifle = new SniperRifle(); sniperRifle.setBulletNum(100); SubmachineGun submachineGun = new SubmachineGun(); submachineGun.setBulletNum(50); AntitankGrenade antitankGrenade = new AntitankGrenade(); antitankGrenade.setBomb(false); FlashBomb flashBomb = new FlashBomb(); flashBomb.setBomb(false); Pack pack1 = new Pack(); pack1.setMainArms(sniperRifle); pack1.setPackNo(1); pack1.setThrowArms(antitankGrenade); Pack pack2 = new Pack(); pack2.setMainArms(submachineGun); pack2.setPackNo(2); pack2.setThrowArms(flashBomb); pack1.getMainArms().aim(); pack1.getMainArms().fire(); pack1.getThrowArms().bomb(); pack2.getMainArms().aim(); pack2.getMainArms().fire(); pack2.getThrowArms().bomb(); } }
http://www.cnblogs.com/rexfang/p/6676273.html