策略模式

smile

大家好:我叫石頭!

為什么出現(xiàn)策略模式:

完成一項(xiàng)任務(wù),往往可以有多種不同的方式,每一種方式稱(chēng)為一個(gè)策略,我們可以根據(jù)環(huán)境或者條件的不同選擇不同的策略來(lái)完成該項(xiàng)任務(wù)。
---對(duì)象行為型模式。

優(yōu)點(diǎn):

  • 策略模式提供了對(duì)“開(kāi)閉原則”的完美支持,用戶(hù)可以在不修改原有系統(tǒng)的基礎(chǔ)上選擇算法或行為,也可以靈活地增加新的算法或行為。
  • 策略模式提供了管理相關(guān)的算法族的辦法。策略模式提供了可以替換繼承關(guān)系的辦法。
  • 使用策略模式可以避免使用多重條件轉(zhuǎn)移語(yǔ)句。

結(jié)構(gòu)圖:

策略模式包含如下角色:

Context: 環(huán)境類(lèi)
Strategy: 抽象策略類(lèi)
ConcreteStrategy: 具體策略類(lèi)

UML
策略模式代碼實(shí)現(xiàn)
# Strategy: 抽象策略類(lèi)
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è)計(jì)(Object-Oriented Design,OOD),其實(shí)體現(xiàn)的是繼承跟多態(tài),

  • 幾個(gè)類(lèi)的主要邏輯相同,只在部分邏輯的算法和行為上稍有區(qū)別的情況。
  • 有幾種相似的行為,或者說(shuō)算法,客戶(hù)端需要?jiǎng)討B(tài)地決定使用哪一種,那么可以使用策略模式,將這些算法封裝起來(lái)供客戶(hù)端調(diào)用。

一般來(lái)說(shuō),策略模式不會(huì)單獨(dú)使用,跟模版方法模式、工廠模式等混合使用的情況比較多。

在android中的應(yīng)用:

1.adapter anim.setInterpolator(new AccelerateInterpolator(2f));
2.屬性動(dòng)畫(huà)
3.volley

在屬性動(dòng)畫(huà)中,有一個(gè)東西叫做插值器,它的作用就是根據(jù)時(shí)間流逝的百分比來(lái)來(lái)計(jì)算出當(dāng)前屬性值改變的百分比.

Context: 環(huán)境類(lèi)

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: 抽象策略類(lèi)
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插值器實(shí)現(xiàn)了Interpolator接口,并且是一個(gè)抽象類(lèi)
abstract public class BaseInterpolator implements Interpolator {
    private int mChangingConfiguration;
    /**
     * @hide
     */
    public int getChangingConfiguration() {
        return mChangingConfiguration;
    }

    /**
     * @hide
     */
    void setChangingConfiguration(int changingConfiguration) {
        mChangingConfiguration = changingConfiguration;
    }
}  

為什么還要封裝成一層抽象類(lèi)呢?
方便抽取一些公共的實(shí)現(xiàn)跟必須的一些實(shí)現(xiàn).
ConcreteStrategy: 具體策略類(lèi)
線性插值器
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();
    }
}

隨便說(shuō)一句:
各種設(shè)計(jì)模式的出現(xiàn)都是為了提高代碼的健壯性等.

Volley實(shí)現(xiàn)
public interface RetryPolicy {


    public int getCurrentTimeout();//獲取當(dāng)前請(qǐng)求用時(shí)(用于 Log)


    public int getCurrentRetryCount();//獲取已經(jīng)重試的次數(shù)(用于 Log)


    public void retry(VolleyError error) throws VolleyError;//確定是否重試,參數(shù)為這次異常的具體信息。在請(qǐng)求異常時(shí)此接口會(huì)被調(diào)用,可在此函數(shù)實(shí)現(xiàn)中拋出傳入的異常表示停止重試。
}
默認(rèn)實(shí)現(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)絡(luò)請(qǐng)求框架,或多或少都會(huì)使用到緩存,緩存一般會(huì)定義一個(gè)Cache接口,然后實(shí)現(xiàn)不同的緩存策略,如內(nèi)存緩存,磁盤(pán)緩存等等,這個(gè)緩存的實(shí)現(xiàn),其實(shí)也可以使用策略模式。直接看Volley,里面也有緩存。

策略模式在MVP中的實(shí)現(xiàn):

  • 提示:Context類(lèi)不一定只有一個(gè)algorithm(),只要是持有interface接口的類(lèi)都能當(dāng)做Context

我們常使用的MVP模式中的Presenter層就是對(duì)策略模式的實(shí)現(xiàn),一個(gè)View在不同的條件下,可以對(duì)應(yīng)不同的Presenter層。

MVP中的策略模式

iOS設(shè)計(jì)模式-策略模式

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1 場(chǎng)景問(wèn)題# 1.1 報(bào)價(jià)管理## 向客戶(hù)報(bào)價(jià),對(duì)于銷(xiāo)售部門(mén)的人來(lái)講,這是一個(gè)非常重大、非常復(fù)雜的問(wèn)題,對(duì)不同的...
    七寸知架構(gòu)閱讀 5,243評(píng)論 9 62
  • 1 場(chǎng)景問(wèn)題 1.1 報(bào)價(jià)管理 向客戶(hù)報(bào)價(jià),對(duì)于銷(xiāo)售部門(mén)的人來(lái)講,這是一個(gè)非常重大、非常復(fù)雜的問(wèn)題,對(duì)不同的客戶(hù)要...
    4e70992f13e7閱讀 3,207評(píng)論 2 16
  • 1.問(wèn)題例1:一個(gè)菜單功能能夠根據(jù)用戶(hù)的“皮膚”首選項(xiàng)來(lái)決定是否采用水平的還是垂直的排列形式。同事可以靈活增加菜單...
    小飛豬閱讀 416評(píng)論 0 0
  • 目錄 本文的結(jié)構(gòu)如下: 引言 什么是策略模式 模式的結(jié)構(gòu) 典型代碼 代碼示例 策略模式和模板方法模式的區(qū)別 優(yōu)點(diǎn)和...
    w1992wishes閱讀 956評(píng)論 1 7
  • 這幾天,我經(jīng)歷了人生中最昏暗的日子,公公急性心梗發(fā)作,做了支架手術(shù),還沒(méi)有度過(guò)安全期又突發(fā)腦出血,進(jìn)行了開(kāi)顱手術(shù)。...
    笑笑媽521閱讀 197評(píng)論 0 0

友情鏈接更多精彩內(nèi)容