欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

策略模式及Android源码中的应用解析

程序员文章站 2022-05-21 16:29:53
策略模式 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使他们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。 使用场景: 1. 针对同一类型问题的多种...

策略模式

策略模式定义了一系列的算法,并将每一个算法封装起来,而且使他们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。

使用场景:
1. 针对同一类型问题的多种处理方式,仅仅是具体行为有差别时。
2. 需要安全地封装多种同一类型的操作时。
3. 出现同一抽象类有多个子类,而又需要使用if-else或者switch-case来选择具体子类时。

使用栗子:
计算价格,初级会员没有折扣,中级会员打9折,高级会员打8折。如果一般写法,应该是if-else判断他是什么级别的会员,在计算相应的折扣。下面使用策略模式来进行实现:
抽象折扣类

public interface memberstrategy {
    /**
     * 计算图书的价格
     * @param booksprice    图书的原价
     * @return    计算出打折后的价格
     */
    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;
    }
}

价格类

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 strategy1 = new advancedmemberstrategy();
        //创建环境
        price price = new price(strategy1);
        //计算价格
        double quote = price.quote(300);
        system.out.println("图书的最终价格为:" + quote);
    }

}

结果

对于高级会员的折扣为20%
图书的最终价格为:240.0

策略模式和工厂模式的区别

工厂模式 策略模式
创建型的设计模式 行为型的设计模式
关注对象创建 关注行为的选择
黑盒子(无需知道具体的实现过程) 白盒子(知道具体的实现过程)

listadapter

listview 是一个很重要的组件,我们通常在布局里写个 listview 组件,然后在代码中 setadapter,把 view 与 model 结合的任务交给了 adapter。

当更换 adapter 的具体实现时,仍然调用的是 listview.setadapter(…) 方法,传入的是arrayadapter或baseadapter等,查看 listview 源码,发现 setadapter 方法的参数是一个 listadapter,如下:

    @override
    public void setadapter(listadapter adapter) {
    ........
    }
public interface listadapter extends adapter{
    .........
} 

可以看到 listadapter 是一个接口,arrayadapter 和 baseadapter 是它的一个实现类。

可以发现 listadapter 就是 strategy 接口,arrayadpater 等就是具体的实现类,而在 listview 中引用的是 接口 listadapter,可以证实这就是一个 策略模式 的使用。

timeinterpolator

时间插值器,它是一个接口,定义了动画改变的速率,允许动画进行非匀速变化。
我们在使用属性动画时,可以根据需要选择合适的时间插值器:

        objectanimator animator = objectanimator.offloat(view, view.alpha, 0f, 1f);
        animator.setinterpolator(new accelerateinterpolator());  //加速
        animator.setinterpolator(new overshootinterpolator());   //跑过头又返回来

和 listview 的 setadapter 一样,valueanimator 的 setinterpolator 方法中也引用的是 接口 timeinterpolator:

    @override
    public void setinterpolator(timeinterpolator value) {
        if (value != null) {
            minterpolator = value;
        } else {
            minterpolator = new linearinterpolator();
        }
    }

timeinterpolator 源码及类结构:

public interface timeinterpolator {

    float getinterpolation(float input);
}

因此这里也是应用了策略模式。。。