Android中的策略模式

策略模式属于对象的行为模式。其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化。

有一个商店,它有初级、中级、高级会员三种级别,未来也可能会添加新的会员种类。对于不同的会员,折扣模式是不一样的,传统的方法可能会进行if判断,不同的会员进行不同的折扣,但这明显的不利于折扣和定制,所以,我们可以使用策略模式,每种会员对应一个策略,这样对应不同的会员我们直接使用不同的策略就可以了,并且我们还可以随时的添加新的策略。

因为每个会员对应不要的策略,所以可以定义一个统一的策略接口,不同的会员可以有不同的实现。

public interface MemberStrategy {
    public double calcPrice(double booksPrice);
}

初级会员直接是原价

public class PrimaryMemberStrategy implements MemberStrategy {

    @Override
    public double calcPrice(double booksPrice) {

        System.out.println("对于初级会员的没有折扣");
        return booksPrice;
    }

}

中级会员九折

public class IntermediateMemberStrategy implements MemberStrategy {

    @Override
    public double calcPrice(double booksPrice) {

        System.out.println("对于中级会员的折扣为10%");
        return booksPrice * 0.9;
    }

}

高级会员八折

public class AdvancedMemberStrategy implements MemberStrategy {

    @Override
    public double calcPrice(double booksPrice) {

        System.out.println("对于高级会员的折扣为20%");
        return booksPrice * 0.8;
    }
}

可以看到,上面对应不要的会员定制了不同的策略,这样我们也可以随时扩展,例如我们想添加一个黄金VIP,很容易直接定义一个实现就可以了。

针对不同的会员,定义好了不同的策略之后,可以看到这个实现我们可以随意实现,它不会影响业务,下面就是根据需要来使用这些策略了。

下个写个Price类,它可以根据传进来的不同策略得到不同会员的价格,这就方便多了,需要什么样的价格,只有给它一个策略就可以了。并且策略跟Price类实现了低耦合。

public class Price {
    //持有一个具体的策略对象
    private MemberStrategy strategy;
    /**
     * 构造函数,传入一个具体的策略对象
     * @param strategy    具体的策略对象
     */
    public Price(MemberStrategy strategy){
        this.strategy = strategy;
    }

    /**
     * 计算图书的价格
     * @param booksPrice    图书的原价
     * @return    计算出打折后的价格
     */
    public double quote(double booksPrice){
        return this.strategy.calcPrice(booksPrice);
    }
}

下面,在客户端中,我们就可以针对不同的会员,给它不同的策略得到不同的价格了。

public class Client {

    public static void main(String[] args) {
        //选择并创建需要使用的策略对象
        MemberStrategy strategy = new AdvancedMemberStrategy();
        //创建环境
        Price price = new Price(strategy);
        //计算价格
        double quote = price.quote(300);
        System.out.println("图书的最终价格为:" + quote);
    }

}

这样我们就可以自己来指定不同的策略了,非常方便。

策略模式的结构

这里写图片描述

环境(Context)角色:持有一个Strategy的引用。

抽象策略(Strategy)角色:这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。

具体策略(ConcreteStrategy)角色:包装了相关的算法或行为。

比如排序,官方告诉大家我这里有一个排序的接口ISort的sort()方法,然后民间各尽其能,实现这个排序的方法:冒泡,快速,堆等等。
这些方法就是“不同的策略”。

在Java中的Comparator就是策略模式,Comparator是一个策略接口,具体的比较方法可以根据需求就行实现。这样就可以根据自己的比较方法来进行比较大小了。

比如:你想对整数采用绝对值大小来排序,Integer 是不符合要求的,你不需要去修改 Integer 类(实际上你也不能这么做)去改变它的排序行为,只要使用一个实现了 Comparator 接口的对象来实现控制它的排序就行了。

public class AbsComparator implements Comparator   {     
    public int compare(Object o1, Object o2)   {     
      int v1 = Math.abs(((Integer)o1).intValue());     
      int v2 = Math.abs(((Integer)o2).intValue());     
      return v1 > v2 ? 1 : (v1 == v2 ? 0 : -1);     
    }     
}

public class Test {
    public static void main(String[] args) {
        //产生一个20个随机整数的数组(有正有负)     
      Random rnd = new Random();     
      Integer[] integers = newInteger[20];     
      for(int i = 0; i < integers.length; i++)     
        integers[i] = new Integer(rnd.nextInt(100) * (rnd.nextBoolean() ? 1 : -1));  

        System.out.println("用AbsComparator排序:");
        Arrays.sort(integers,new AbsComparator());  
        System.out.println(Arrays.asList(integers));
    }   

}

在Android中,Animation不同动画的实现,主要是依靠Interpolator的不同实现而变。它使用的也是策略模式,可以根据需要实现Interpolator,得到不同的动画实现。

这里写图片描述

定义接口Interpolator:

public interface Interpolator {

    float getInterpolation(float input);
}

我们以LinearInterpolator为例,实现具体的策略,代码如下:

public class LinearInterpolator implements Interpolator {  

    public LinearInterpolator() {  
    }  

    public LinearInterpolator(Context context, AttributeSet attrs) {  
    }  

    public float getInterpolation(float input) {  
        return input;  
    }  
}

我们自定义插值器的时候,只需要重写getInterpolation方法,其中传入的input参数就是时间流逝的百分比,这个百分比就是当前时间的流逝除以设置的持续时间Duration来得到的。我们实现这个函数的时候,可以通过改变这个值来实现我们想要的效果。

public void startAnimation(View view)  
{  

    ValueAnimator valueAnimator = new ValueAnimator();  
    valueAnimator.setDuration(3000);  
    //这个地方设置了变化值的类型
    valueAnimator.setObjectValues(new PointF(0, 0));  
    //设置插值器
    valueAnimator.setInterpolator(new LinearInterpolator());  

    valueAnimator.start();  
    valueAnimator.addUpdateListener(new AnimatorUpdateListener()  
    {  
        @Override  
        public void onAnimationUpdate(ValueAnimator animation)  
        {  
            // 得到估值器里面的那个返回值
            PointF point = (PointF) animation.getAnimatedValue();
            //设置属性值  
            mBlueBall.setX(point.x);  
            mBlueBall.setY(point.y);  

        }  
    });  
}  

可以看到,我们可以为动画指定Interpolator策略来实现不同的效果,这个策略我们可以自己制定实现。

通过以上也可以看出策略模式的优缺点:

优点:

结构清晰明了、使用简单直观。
耦合度相对而言较低,扩展方便。
操作封装也更为彻底,数据更为安全。

缺点:

随着策略的增加,子类也会变得繁多。

参照文章:

《JAVA与模式》之策略模式

Android设计模式源码解析之策略模式

Android设计模式系列(11)–SDK源码之策略模式

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值