
前兩篇文章分別介紹了Builder模式和Observer模式,本文將介紹另一種Android里面經(jīng)常用到的設(shè)計(jì)模式,策略模式。
策略模式是一種通俗易懂的設(shè)計(jì)模式,常用于組織一些可替換的算法組件,這些算法組件本質(zhì)上完成同一個(gè)性質(zhì)的任務(wù),可以互相替換,只是實(shí)現(xiàn)細(xì)節(jié)上存在些許差異。
舉個(gè)例子,為了完成射擊敵人的任務(wù),我們可以采取不同的武器進(jìn)行,手槍,步槍,或者火炮。這里不同的武器就是不同的策略,這些策略可以互相替換,并且都可以實(shí)現(xiàn)射擊敵人的任務(wù),區(qū)別在于執(zhí)行過程的差異。
利用策略模式,我們可以采用如下的代碼實(shí)現(xiàn)。
首先抽象出不同射擊策略共同的接口:
ShootInterface.java
public interface ShootInterface {
void shoot();
}
該接口包含了射擊接口,不同武器實(shí)現(xiàn)不同的射擊函數(shù)。
手槍射擊:
PistolStrategy.java
public class PistolStrategy implements ShootInterface{
@Override
public void shoot() {
System.out.println("Pistol shooting, kills 1 enemy every 10 shots.");
}
}
步槍射擊:
RifleStrategy.java
public class RifleStrategy implements ShootInterface{
@Override
public void shoot() {
System.out.println("Rifle shooting, one shot, one kill.");
}
}
火炮射擊:
CannonStrategy.java
public class CannonStrategy implements ShootInterface {
@Override
public void shoot() {
System.out.println("Cannon shooting, one shot, kills a lot.");
}
}
新建一個(gè)消滅敵人的任務(wù)類:
EliminateEneryTask.java
public class EliminateEneryTask {
private ShootInterface shootStrategy;
public void setShootStrategy(ShootInterface strategy) {
shootStrategy = strategy;
}
public void action() {
shootStrategy.shoot();
}
}
這個(gè)類的setShootStrategy函數(shù)用于外部調(diào)用來設(shè)置具體的設(shè)計(jì)策略,action方法實(shí)施該策略下的射擊動(dòng)作。
調(diào)用如下:
public class StrategyPatternDemo {
public static void main(String[] args) {
PistolStrategy pistol = new PistolStrategy();
RifleStrategy rifle = new RifleStrategy();
CannonStrategy cannon = new CannonStrategy();
EliminateEneryTask task = new EliminateEneryTask();
task.setShootStrategy(pistol);
task.action();
task.setShootStrategy(rifle);
task.action();
task.setShootStrategy(cannon);
task.action();
}
}
這種模式下,我們新添加一種射擊策略也很簡(jiǎn)單,只需要新加一個(gè)實(shí)現(xiàn)了ShootInterface接口的類,并實(shí)現(xiàn)shoot方法即可,無需修改EliminateEneryTask類。同樣的需求如果不使用策略模式,我們可能需要在EliminateEneryTask里面設(shè)置一系列的if/else進(jìn)行策略的判斷,顯然不如這種方式優(yōu)雅。
在Android屬性動(dòng)畫中,ValueAnimator類的插值器(Interpolator)就使用了策略模式:
ValueAnimator animator = ValueAnimator.ofInt(0,600);
animator.setDuration(1000);
animator.setInterpolator(new LinearInterpolator());
animator.start();
通過ValueAnimator的setInterpolator函數(shù),可以設(shè)置不同的插值器,也就是不同的插值策略,比如線性插值器LinearInterpolator,加速度插值器AccelerateInterpolator,減速度插值器DecelerateInterpolator等。它們都實(shí)現(xiàn)了TimeInterpolator接口,完成各自的插值計(jì)算,并提供統(tǒng)一的對(duì)外調(diào)用函數(shù):
public interface TimeInterpolator {
float getInterpolation(float input);
}
這樣就可以通過setInterpolator設(shè)置任意的插值策略,包括自己實(shí)現(xiàn)的策略。
像策略這種設(shè)計(jì)模式,本身并沒有什么高深的地方,只要了解過一次,就能簡(jiǎn)單的套用在日常編程中,運(yùn)用得當(dāng)?shù)脑?,能顯著提高代碼質(zhì)量,是一種低成本,高收益的設(shè)計(jì)模式。