名称: 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);
}
}