在平常開發工做中,適當的使用一些設計模式,可讓代碼擴展性更強,能更好地擁抱變化,讓代碼更加優雅。本文主要介紹設計模式中的策略模式,並附上測試示例 Demo 供你們參考。算法
策略模式定義了一系列的算法,並將每個算法封裝起來,並且使它們還能夠相互替換。策略模式讓算法獨立於使用它的客戶而獨立變化。編程
策略模式,針對那些動做因對象而異的狀況下,把每個動做都獨立封裝起來並實現同一個接口,經過組合的方式賦予對象相對應的動做,從而使得全部的動做均可以相互替換。經過策略模式,能夠達到在運行時修改對象的具體動做、對象和具體動做之間解耦的效果。設計模式
1)找出應用中可能須要變化的地方,把它們獨立出來,不要和那些不須要變化的代碼混在一塊兒;ide
2)面向接口編程,而不是面向實現編程;測試
3)多用組合,少用繼承;this
這裏我以 CF 裏面的揹包爲例子來描述策略模式(有可能 CF 揹包的設計不是我講的這樣,這裏只是舉例說明策略模式)。玩過 CF 的同窗都知道,每一個角色都有本身的揹包,揹包裏面能夠放主武器、副武器、投擲類武器等。而這幾類武器,又包含多種具體型號的武器,好比:主武器能夠是狙擊步槍、衝鋒槍,副武器能夠是普通手槍、左輪手槍,投擲類武器能夠是手雷、煙霧彈、閃光彈等。爲了可以達到可以隨時調整揹包裝備的效果,能夠採用策略模式。UML 圖以下:spa
從上面的 UML 能夠看出,先定義一個主武器的接口類 IMainArms 和投擲類武器的接口類 IThrowArms,而後讓狙擊步槍類 SniperRifle 和 衝鋒槍類 SubmachineGun 都去實現主武器接口,讓手雷類 AntitankGrenade 、閃光彈類 FlashBomb 和 煙霧彈類 SmokeBomb 都去實現投擲類武器接口,接着再在揹包類 Pack 中經過 IMainArms 和 IThrowArms 兩個接口聲明一個主武器變量和一個投擲類武器的變量。至此,在配置揹包時,就能夠根據實際須要,往揹包裏面放不一樣的主武器和不一樣的投擲類武器,若是有新的主武器或者投擲類武器須要建立,則只須要在建立對應的類時,以相同的方式實現對應的接口後,便可像原有的武器使用方式使用新的武器。設計
IMainArms 主武器接口code
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("狙擊槍扣動扳機..."); this.bulletNum = this.bulletNum - 1; } } @Override public void aim() { System.out.println("狙擊槍瞄準..."); } 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("衝鋒槍扣動扳機..."); this.bulletNum = this.bulletNum - 1; } } @Override public void aim() { System.out.println("衝鋒槍瞄準..."); } 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 測試類
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(); } }