阅读 51

Strategy策略设计模式

名称: Strategy 策略模式

概要: 一个接口定义一系列函数, 把他们的实现封装到各个类中, 通过抽象使他们可以在运行时动态切换

interface Strategy{
	void doOperation()
}

class OperationAdd implements Strategy

public class Context {
   Strategy stragtegy
      
      Context(Strategy stragtegy){
          this.stragtegy = stragtegy;
      }   
      execute(){
          stragtegy.doOperation()
      }
}

复制代码

动机:

  • 当前你有大量 if else 可以使用它来解耦
  • 利用了继承和多态, 扩展性好
  • 策略类需要暴露给外界, 外界需要知道每个算法的功能, 才能使用
  • 策略实现类会很多, 而且复用性小

做法:

  • 创建一个接口, 定义一系列方法
  • 创建每个业务策略具体类来实现这个接口
  • 通过一个封装类来包装这个策略, 利用多态让外界传递不同的实现类
  • 调用封装类的包装的方法, 来实现切换不同的逻辑

范例

  • 接口 Strategy
  • 实现类 OperationEat , OperationRun
  • 包装类 Context
interface Strategy{
	void doOperation()
}

class OperationAdd implements Strategy{
   void doOperation(){
	   	System.out.println("eat!")
   }
}

class OperationRun implements Strategy{
   void doOperation(){
	   	System.out.println("run!")
   }
}

public class Context {
  Strategy stragtegy
	
    Context(Strategy stragtegy){ //方便后期扩展不同的实现类
    	this.stragtegy = stragtegy;
    }
	execute(){
	    stragtegy.doOperation()
    }
}

public class StrategyMain{
    public static void main(String[] args) {
      Context(new OperationRun()).execute();
      Context(new OperationEat()).execute();
    }
}

复制代码

实际源码中的使用场景

Glide
  • 接口 LruPoolStrategy
  • 实现类 SizeConfigStrategy AttributeStrategy SizeStrategy
  • 包装类 LruBitmapPool

interface LruPoolStrategy {
    void put(Bitmap bitmap);

    @Nullable
    Bitmap get(int width, int height, Bitmap.Config config);

    @Nullable
    Bitmap removeLast();

    String logBitmap(Bitmap bitmap);

    String logBitmap(int width, int height, Bitmap.Config config);

    int getSize(Bitmap bitmap);
}

在LruBitmapPool的构造方法, 根据系统版本不同, 构造不同的类;

  private static LruPoolStrategy getDefaultStrategy() {
      final LruPoolStrategy strategy;
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        strategy = new SizeConfigStrategy();
      } else {
        strategy = new AttributeStrategy();
      }
      return strategy;
  }
 
 //利用多态实现不同策略 removeLast()
 private synchronized void trimToSize(long size) {
    while (currentSize > size) {
      final Bitmap removed = strategy.removeLast();
      // TODO: This shouldn't ever happen, see #331.
      if (removed == null) {
        if (Log.isLoggable(TAG, Log.WARN)) {
          Log.w(TAG, "Size mismatch, resetting");
          dumpUnchecked();
        }
        currentSize = 0;
        return;
      }
      tracker.remove(removed);
      currentSize -= strategy.getSize(removed);
      evictions++;
      if (Log.isLoggable(TAG, Log.DEBUG)) {
        Log.d(TAG, "Evicting bitmap=" + strategy.logBitmap(removed));
      }
      dump();
      removed.recycle();
    }
  } 
 
    
    
复制代码
Retrofit
  • 接口 CallAdapter
  • 实现类 RxJava2CallAdapter ResponseCallAdapter BodyCallAdapter
  • 包装类 HttpServiceMethod

Retrofit提供 addCallAdapterFactory方法来让外界注入不同的策略实现类,
利用建造者模式持久化这个CallAdapterFactory, 
在需要时取出工厂, 创建CallAdapter实现类, 调用adapt返回执行网络请求的call包装类


它的CallAdapter接口内部有一个Factory抽象类, 每个具体的策略实现类, 都通过factory工厂来初始化.


/**
 * Adapts a {@link Call} with response type {@code R} into the type of {@code T}. Instances are
 * created by {@linkplain Factory a factory} which is
 * {@linkplain Retrofit.Builder#addCallAdapterFactory(Factory) installed} into the {@link Retrofit}
 * instance.
 */
public interface CallAdapter<R, T> {

  T adapt(Call<R> call);

  /**
   * Creates {@link CallAdapter} instances based on the return type of {@linkplain
   * Retrofit#create(Class) the service interface} methods.
   */
  abstract class Factory {
   
    public abstract CallAdapter<?, ?> get(Type returnType, Annotation[] annotations,
        Retrofit retrofit);
}


public CallAdapter<?, ?> nextCallAdapter(
      @Nullable CallAdapter.Factory skipPast, Type returnType, Annotation[] annotations) {
    Objects.requireNonNull(returnType, "returnType == null");
    Objects.requireNonNull(annotations, "annotations == null");

    int start = callAdapterFactories.indexOf(skipPast) + 1;
    for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
      CallAdapter<?, ?> adapter = callAdapterFactories.get(i).get(returnType, annotations, this);
      if (adapter != null) {
        return adapter;
      }
    }
}

默认callAdapter的实现: 

DefaultCallAdapterFactory ==> CallAdapter.Factory 
DefaultCallAdapterFactory.get()对应的是一个匿名内部类来实现的 ==> CallAdapter
CallAdapter.adapt() ===> ExecutorCallbackCall

当利用动态代理拿到代理的接口, 调用接口里的方法时, 会调用callAdapter的adapt方法返回ExecutorCallbackCall对象

ExecutorCallbackCall -> OkHttpCall -> Call(你定义的), 进行层层包装


复制代码
Android 动画 Interpolator
  • 接口 TimeInterpolator
  • 实现类 LinearInterpolator OvershootInterpolator BounceInterpolator
  • 包装类 Animation

public interface TimeInterpolator {
    float getInterpolation(float input);
}


//设置每个策略实现类
animation.setInterpolator(new LinearInterpolator());

动画从这个方法开始执行, invalidate() 通知父类进行draw的重新绘制
public void startAnimation(Animation animation) {
        animation.setStartTime(Animation.START_ON_FIRST_FRAME);
        setAnimation(animation);
        invalidateParentCaches();
        invalidate(true);
}

ViewGroup.drawChild() ==> View.draw() ==> View.applyLegacyAnimation() 
==> Animation.getTransformation()


public boolean getTransformation(long currentTime, Transformation outTransformation) {
        //计算当前时间流逝的百分比
        if (duration != 0) {
            normalizedTime = ((float) (currentTime - (mStartTime + startOffset))) /
                    (float) duration;
        } else {
            // time is a step-change with a zero duration
            normalizedTime = currentTime < mStartTime ? 0.0f : 1.0f;
        }
		//动画是否已经完成
        final boolean expired = normalizedTime >= 1.0f || isCanceled();
        mMore = !expired;

        if ((normalizedTime >= 0.0f || mFillBefore) && (normalizedTime <= 1.0f || mFillAfter)) {
             //根据 getInterpolation 来获取动画执行的百分比
             //策略模式	
            final float interpolatedTime = mInterpolator.getInterpolation(normalizedTime);
            //调用每个animation的子类的applyTransformation
            applyTransformation(interpolatedTime, outTransformation);
        }

        if (!mMore && mOneMoreTime) {
            mOneMoreTime = false;
            return true;
        }

        return mMore;
    }

例如 ScaleAnimation.applyTransformation()

  @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
        float sx = 1.0f;
        float sy = 1.0f;
        float scale = getScaleFactor();

        if (mFromX != 1.0f || mToX != 1.0f) {
            sx = mFromX + ((mToX - mFromX) * interpolatedTime);
        }
        if (mFromY != 1.0f || mToY != 1.0f) {
            sy = mFromY + ((mToY - mFromY) * interpolatedTime);
        }
        
	//改变view的属性
        if (mPivotX == 0 && mPivotY == 0) {
            t.getMatrix().setScale(sx, sy);
        } else {
            t.getMatrix().setScale(sx, sy, scale * mPivotX, scale * mPivotY);
        }
    }


复制代码
文章分类
Android
文章标签