策略模式:定义了一系列的算法,并将每一个算法封装起来,而且使他们可以互相替换。
这种模式在各种插值器中用的很多,比如安卓的属性动画中的插值器,okhttp中的插值器
下面先来个小例子。假如我们需要根据不同的条件来实现不同的动画效果,最常用的就是if-else或者使用switch 如下面
public class AnimationUtil {
void animate(int type){
if(type == 1){
animate1();
}else if(type == 2){
animate2();
}else if(type == 3){
animate3();
}
}
private void animate1(){
//一堆逻辑处理
Log.i("AnimationUtil","先快后慢");
}
private void animate2(){
//一堆逻辑处理
Log.i("AnimationUtil","先转圈后加速");
}
private void animate3(){
//一堆逻辑处理
Log.i("AnimationUtil","先后退在前进");
}
}
运行和结果:
AnimationUtil util = new AnimationUtil();
util.animate(1);
02-23 17:21:14.264 29749-29749/com.chs.androiddailytext I/AnimationUtil: 先快后慢
上面的例子中,根据我们传入的type的值来判断执行哪一种动画。上面的例子很简单无所谓,但是真实的项目中,想要完成一个动画需要写的算法公式是很多很多的,就想上面每个方法里面写的(一堆逻辑)一样。随着我们需要的动画的种类越来越多,我们这个util类会变的非常的臃肿,不容易维护和升级。
我们可以把工具类中的每一种动画的计算方法抽取出来,就清晰多了。如下
先定义一个动画的接口
public interface IAnimate {
void animate();
}
每种需要实现的动画都实现这个接口
public class Animate1 implements IAnimate {
@Override
public void animate() {
//一堆逻辑处理
Log.i("AnimationUtil","先快后慢");
}
}
public class Animate2 implements IAnimate {
@Override
public void animate() {
//一堆逻辑处理
Log.i("AnimationUtil","先转圈后加速");
}
}
public class Animate3 implements IAnimate {
@Override
public void animate() {
//一堆逻辑处理
Log.i("AnimationUtil","先后退在前进");
}
}
定义一个动画控制类
public class AnimateController {
private IAnimate mAnimate;
public void setAnimate(IAnimate animate) {
mAnimate = animate;
}
public void animate(){
mAnimate.animate();
}
}
执行和结果:
AnimateController controller = new AnimateController();
controller.setAnimate(new Animate1());
controller.animate();
02-23 17:21:14.264 29749-29749/com.chs.androiddailytext I/AnimationUtil: 先快后慢
上面的这种方法就是策略模式,根据不同的需求定制不同的算法策略。
优点就是代码结构清晰,比如上面我们可以很清楚的知道我们现在执行的是哪一种动画。当我们需要增加新的动画的时候,只需要写个类实现动画接口然后写对应的逻辑即可。
缺点是随着动画的种类越来越多,相对应的动画的类也会增多。