
smile
大家好:我叫石頭!
為什么出現(xiàn)策略模式:
完成一項任務,往往可以有多種不同的方式,每一種方式稱為一個策略,我們可以根據(jù)環(huán)境或者條件的不同選擇不同的策略來完成該項任務。
---對象行為型模式。
優(yōu)點:
- 策略模式提供了對“開閉原則”的完美支持,用戶可以在不修改原有系統(tǒng)的基礎(chǔ)上選擇算法或行為,也可以靈活地增加新的算法或行為。
- 策略模式提供了管理相關(guān)的算法族的辦法。策略模式提供了可以替換繼承關(guān)系的辦法。
- 使用策略模式可以避免使用多重條件轉(zhuǎn)移語句。
結(jié)構(gòu)圖:
策略模式包含如下角色:
Context: 環(huán)境類
Strategy: 抽象策略類
ConcreteStrategy: 具體策略類

UML
策略模式代碼實現(xiàn)
# Strategy: 抽象策略類
interface IStrategy {
public void doSomething();
}
class ConcreteStrategy1 implements IStrategy {
public void doSomething() {
System.out.println("具體策略1");
}
}
class ConcreteStrategy2 implements IStrategy {
public void doSomething() {
System.out.println("具體策略2");
}
}
class Context {
private IStrategy strategy;
public Context(IStrategy strategy){
this.strategy = strategy;
}
public void execute(){
strategy.doSomething();
}
}
public class Client {
public static void main(String[] args){
Context context;
System.out.println("-----執(zhí)行策略1-----");
context = new Context(new ConcreteStrategy1());
context.execute();
System.out.println("-----執(zhí)行策略2-----");
context = new Context(new ConcreteStrategy2());
context.execute();
}
}
背后的本質(zhì)原理:
在面向?qū)ο笤O(shè)計(Object-Oriented Design,OOD),其實體現(xiàn)的是繼承跟多態(tài),
- 幾個類的主要邏輯相同,只在部分邏輯的算法和行為上稍有區(qū)別的情況。
- 有幾種相似的行為,或者說算法,客戶端需要動態(tài)地決定使用哪一種,那么可以使用策略模式,將這些算法封裝起來供客戶端調(diào)用。
一般來說,策略模式不會單獨使用,跟模版方法模式、工廠模式等混合使用的情況比較多。
在android中的應用:
1.adapter anim.setInterpolator(new AccelerateInterpolator(2f));
2.屬性動畫
3.volley
在屬性動畫中,有一個東西叫做插值器,它的作用就是根據(jù)時間流逝的百分比來來計算出當前屬性值改變的百分比.
Context: 環(huán)境類
private static final TimeInterpolator sDefaultInterpolator =
new AccelerateDecelerateInterpolator();
private TimeInterpolator mInterpolator = sDefaultInterpolator;
@Override
public void setInterpolator(TimeInterpolator value) {
if (value != null) {
mInterpolator = value;
} else {
mInterpolator = new LinearInterpolator();
}
}
@Override
public TimeInterpolator getInterpolator() {
return mInterpolator;
}
Strategy: 抽象策略類
public interface Interpolator extends TimeInterpolator {
// A new interface, TimeInterpolator, was introduced for the new android.animation
// package. This older Interpolator interface extends TimeInterpolator so that users of
// the new Animator-based animations can use either the old Interpolator implementations or
// new classes that implement TimeInterpolator directly.
}
BaseInterpolator插值器實現(xiàn)了Interpolator接口,并且是一個抽象類
abstract public class BaseInterpolator implements Interpolator {
private int mChangingConfiguration;
/**
* @hide
*/
public int getChangingConfiguration() {
return mChangingConfiguration;
}
/**
* @hide
*/
void setChangingConfiguration(int changingConfiguration) {
mChangingConfiguration = changingConfiguration;
}
}
為什么還要封裝成一層抽象類呢?
方便抽取一些公共的實現(xiàn)跟必須的一些實現(xiàn).
ConcreteStrategy: 具體策略類
線性插值器
public class LinearInterpolator extends BaseInterpolator implements NativeInterpolatorFactory {
public LinearInterpolator() {
}
public LinearInterpolator(Context context, AttributeSet attrs) {
}
public float getInterpolation(float input) {
return input;
}
/** @hide */
@Override
public long createNativeInterpolator() {
return NativeInterpolatorFactoryHelper.createLinearInterpolator();
}
}
加減速插值器
public class AccelerateDecelerateInterpolator extends BaseInterpolator
implements NativeInterpolatorFactory {
public AccelerateDecelerateInterpolator() {
}
@SuppressWarnings({"UnusedDeclaration"})
public AccelerateDecelerateInterpolator(Context context, AttributeSet attrs) {
}
public float getInterpolation(float input) {
return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;
}
/** @hide */
@Override
public long createNativeInterpolator() {
return NativeInterpolatorFactoryHelper.createAccelerateDecelerateInterpolator();
}
}
隨便說一句:
各種設(shè)計模式的出現(xiàn)都是為了提高代碼的健壯性等.
Volley實現(xiàn)
public interface RetryPolicy {
public int getCurrentTimeout();//獲取當前請求用時(用于 Log)
public int getCurrentRetryCount();//獲取已經(jīng)重試的次數(shù)(用于 Log)
public void retry(VolleyError error) throws VolleyError;//確定是否重試,參數(shù)為這次異常的具體信息。在請求異常時此接口會被調(diào)用,可在此函數(shù)實現(xiàn)中拋出傳入的異常表示停止重試。
}
默認實現(xiàn)
public class DefaultRetryPolicy implements RetryPolicy {
...
}
public abstract class Request<T> implements Comparable<Request<T>> {
private RetryPolicy mRetryPolicy;
public Request<?> setRetryPolicy(RetryPolicy retryPolicy) {
mRetryPolicy = retryPolicy;
return this;
}
public RetryPolicy getRetryPolicy() {
return mRetryPolicy;
}
}
各大網(wǎng)絡請求框架,或多或少都會使用到緩存,緩存一般會定義一個Cache接口,然后實現(xiàn)不同的緩存策略,如內(nèi)存緩存,磁盤緩存等等,這個緩存的實現(xiàn),其實也可以使用策略模式。直接看Volley,里面也有緩存。
策略模式在MVP中的實現(xiàn):
- 提示:Context類不一定只有一個algorithm(),只要是持有interface接口的類都能當做Context
我們常使用的MVP模式中的Presenter層就是對策略模式的實現(xiàn),一個View在不同的條件下,可以對應不同的Presenter層。

MVP中的策略模式