大家好:我叫石頭!
為什么出現(xiàn)策略模式:
完成一項(xiàng)任務(wù),往往可以有多種不同的方式,每一種方式稱為一個(gè)策略,我們可以根據(jù)環(huán)境或者條件的不同選擇不同的策略來完成該項(xiàng)任務(wù)。
---對(duì)象行為型模式昆禽。
優(yōu)點(diǎn):
- 策略模式提供了對(duì)“開閉原則”的完美支持,用戶可以在不修改原有系統(tǒng)的基礎(chǔ)上選擇算法或行為蝇庭,也可以靈活地增加新的算法或行為醉鳖。
- 策略模式提供了管理相關(guān)的算法族的辦法。策略模式提供了可以替換繼承關(guān)系的辦法哮内。
- 使用策略模式可以避免使用多重條件轉(zhuǎn)移語句盗棵。
結(jié)構(gòu)圖:
策略模式包含如下角色:
Context: 環(huán)境類
Strategy: 抽象策略類
ConcreteStrategy: 具體策略類
策略模式代碼實(shí)現(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è)計(jì)(Object-Oriented Design
,OOD),其實(shí)體現(xiàn)的是繼承跟多態(tài),
- 幾個(gè)類的主要邏輯相同牍蜂,只在部分邏輯的算法和行為上稍有區(qū)別的情況漾根。
- 有幾種相似的行為,或者說算法鲫竞,客戶端需要?jiǎng)討B(tài)地決定使用哪一種辐怕,那么可以使用策略模式,將這些算法封裝起來供客戶端調(diào)用从绘。
一般來說寄疏,策略模式不會(huì)單獨(dú)使用,跟模版方法模式僵井、工廠模式等混合使用的情況比較多陕截。
在android中的應(yīng)用:
1.adapter anim.setInterpolator(new AccelerateInterpolator(2f));
2.屬性動(dòng)畫
3.volley
在屬性動(dòng)畫中,有一個(gè)東西叫做插值器,它的作用就是根據(jù)時(shí)間流逝的百分比來來計(jì)算出當(dāng)前屬性值改變的百分比.
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插值器實(shí)現(xiàn)了Interpolator接口,并且是一個(gè)抽象類
abstract public class BaseInterpolator implements Interpolator {
private int mChangingConfiguration;
/**
* @hide
*/
public int getChangingConfiguration() {
return mChangingConfiguration;
}
/**
* @hide
*/
void setChangingConfiguration(int changingConfiguration) {
mChangingConfiguration = changingConfiguration;
}
}
為什么還要封裝成一層抽象類呢?
方便抽取一些公共的實(shí)現(xiàn)跟必須的一些實(shí)現(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è)計(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)存緩存,磁盤緩存等等淌实,這個(gè)緩存的實(shí)現(xiàn)冻辩,其實(shí)也可以使用策略模式猖腕。直接看Volley,里面也有緩存恨闪。
策略模式在MVP中的實(shí)現(xiàn):
- 提示:Context類不一定只有一個(gè)algorithm(),只要是持有interface接口的類都能當(dāng)做Context
我們常使用的MVP模式中的Presenter層就是對(duì)策略模式的實(shí)現(xiàn)倘感,一個(gè)View在不同的條件下,可以對(duì)應(yīng)不同的Presenter層咙咽。