寻找android中的设计模式(二)


  1. 概述

    前面学习了单例模式和观察者模式,其中观察者模式可以很好的降低对象直接的耦合。后面的模式会接触到更多的设计原则。

  2. 寻找策略模式

    定义:定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。

    学完之后,我也思考着生活当中哪些地方可以使用到。就以游戏为例吧,需求描述是:有很多个英雄,每个英雄都有自己的技能和坐骑。用户可以随意定制英雄的技能和坐骑。


  1. 根据策略模式,我们先把会变化的技能和坐骑抽出来,定义两个接口:

    public interface IAttackBehavior {public void attack();}
    public interface IMountBehavior {public void mount();}

  2. 根据接口实现现有的几个算法,也就是各种技能和坐骑。简单举几个:

    public class FireAttack implements IAttackBehavior {@Overridepublic void attack() {System.out.println("火攻击");}}
    public class WaterAttack implements IAttackBehavior {@Overridepublic void attack() {System.out.println("水攻击");}}
    public class ElectricAttack implements IAttackBehavior {@Overridepublic void attack() {System.out.println("电攻击");}}

    public class HorseMount implements IMountBehavior {@Overridepublic void mount() {System.out.println("骑马坐骑");}}
    public class CarMount implements IMountBehavior {@Overridepublic void mount() {System.out.println("开车坐骑");}}

    public class AirMount implements IMountBehavior {@Overridepublic void mount() {System.out.println("飞行坐骑");}}


  3. 有了不同的算法,我们定义一个英雄的父类,将技能和坐骑组合进来。

    public abstract class Hero {protected String name;private IAttackBehavior attackBehavior;private IMountBehavior mountBehavior;public Hero setAttackBehavior(IAttackBehavior attackBehavior) {this.attackBehavior = attackBehavior;return this;}public Hero setMountBehavior(IMountBehavior mountBehavior) {this.mountBehavior = mountBehavior;return this;}public void attack() {this.attackBehavior.attack();}public void mount() {this.mountBehavior.mount();}}

    这样就可以给英雄设置不同的技能和坐骑。

  4. 实现几个英雄(客户)

    public class HeroA extends Hero {public HeroA(String name) {this.name = name;System.out.println(name);}}
    public class HeroB extends Hero {public HeroB(String name) {this.name = name;}}

    可以看到客户(英雄)和算法(技能和坐骑)完全独立。

  5. 测试

    public static void main(String[] args) {Hero heroA = new HeroA("英雄A");heroA.setAttackBehavior(new FireAttack()).setMountBehavior(new AirMount());heroA.attack();heroA.mount();}

    打印结果:

    英雄A火攻击飞行坐骑

    该模式的好处是当需要增加一种算法(技能)可以任意添加。而且可以很方便的给客户(英雄)定制算法(技能)。

    接着寻找android源码中的该模式:


    1. 动画插值器Interpolator

      插值器的主要作用是可以控制动画的变化速率。它类似上面的算法,可以给动画定制不同的变化速率。下面是google提供的一些插值器实现类:


      TimeInterpolator是一个接口:

      public interface TimeInterpolator {    /**     * Maps a value representing the elapsed fraction of an animation to a value that represents     * the interpolated fraction. This interpolated value is then multiplied by the change in     * value of an animation to derive the animated value at the current elapsed animation time.     *     * @param input A value between 0 and 1.0 indicating our current point     *        in the animation where 0 represents the start and 1.0 represents     *        the end     * @return The interpolation value. This value can be more than 1.0 for     *         interpolators which overshoot their targets, or less than 0 for     *         interpolators that undershoot their targets.     */    float getInterpolation(float input);}

      找到了算法类(各种插值器)和接口后,下面看下属性动画类ValueAnimator中如何使用:

          // The time interpolator to be used if none is set on the animation    private static final TimeInterpolator sDefaultInterpolator =            new AccelerateDecelerateInterpolator();

          /**     * The time interpolator to be used. The elapsed fraction of the animation will be passed     * through this interpolator to calculate the interpolated fraction, which is then used to     * calculate the animated values.     */    private TimeInterpolator mInterpolator = sDefaultInterpolator;
          /**     * The time interpolator used in calculating the elapsed fraction of this animation. The     * interpolator determines whether the animation runs with linear or non-linear motion,     * such as acceleration and deceleration. The default value is     * {@link android.view.animation.AccelerateDecelerateInterpolator}     *     * @param value the interpolator to be used by this animation. A value of <code>null</code>     * will result in linear interpolation.     */    @Override    public void setInterpolator(TimeInterpolator value) {        if (value != null) {            mInterpolator = value;        } else {            mInterpolator = new LinearInterpolator();        }    }

      这里的ValueAnimator相当客户类,它的父类Animator是一个超类,类似上面英雄的父类。客户类ValueAnimator默认给了一个 AccelerateDecelerateInterpolator插值器(先加速后减速)。我们可以给客户设置不同的插值器(DecelerateInterpolatorAcceleratelnterpolator等);

      从动画插值器的设计来分析,它封装了变化即将各种算法(插值器)独立起来,将插值器组合进来没有用继承。对于ValueAnimator只针对客户,不针对插值器的算法,符合针对接口编程,不针对实现编程。

    2. 列表适配器

      android列表显示数据的开发流程一般是这样的:获取数据-》定义一个包含该数据的适配器-》定义一个列表-》给列表设置这个适配器。

      思考一下,是否符合策略模式呢?

      我认为是符合的,适配器是算法,可以有不同的算法(适配器),列表是客户,可以有多个客户(列表布局、网格布局)。而且客户完全独立与算法。下面查找下是否符合OO设计原则。首先看下算法(适配器)是否实现接口:

      public interface ListAdapter extends Adapter {

      public abstract class BaseAdapter implements ListAdapter, SpinnerAdapter {

      可以看到确实是的。接着看下客户listview是否针对接口编程:

          public void setAdapter(ListAdapter adapter) {        if (mAdapter != null && mDataSetObserver != null) {            mAdapter.unregisterDataSetObserver(mDataSetObserver);        }        resetList();        mRecycler.clear();        if (mHeaderViewInfos.size() > 0|| mFooterViewInfos.size() > 0) {            mAdapter = new HeaderViewListAdapter(mHeaderViewInfos, mFooterViewInfos, adapter);        } else {            mAdapter = adapter;        }

      可以看到客户不会自己去实现一个算法(适配器),而是把算法设置进来使用。不仅封装了变化,而且将接口组合。


      学完了策略模式后,对设计原则有了简单的了解。当然仅仅是学会了几条要领,要掌握精髓,还需不断练习。目前涉及OO原则如下:


        1. 封装变化

        2. 多用组合,少用继承

        3. 针对接口编程,不针对实现编程

        4. 为交互对象之间的松耦合设计而努力

        5. 类应该对扩展开发,对修改关闭

        6. 依赖抽象,不要依赖具体类




更多相关文章

  1. Android比iOS卡得原因和本质区别总结
  2. android 实现从网络上抓取图片并显示在手机上
  3. Android(安卓)ZXing 二维码、条形码扫描介绍
  4. 为什么Android应用用Java开发,为什么Android大型游戏要用数据包?这
  5. 微软推超酷应用on{x} 能远程控制Android手机
  6. Android多人视频聊天应用的开发(三)多人聊天
  7. Android智能电视开发之明星UI---RecyclerView
  8. 【设计模式与Android】原型模式——复制中心走出来的克隆人
  9. 五月小结

随机推荐

  1. 【Android(安卓)studio】No cached versi
  2. android 之json对象解析并展示(含json解
  3. Android(安卓)SystemServer学习之二
  4. Android系统之System Server大纲
  5. Android 记忆卡片游戏 记忆力 Android游
  6. 移动端开发三国时代
  7. android 快速滚动条设置(像新浪微博,滚动
  8. Android判断两个时间的间隔
  9. Android中开发版(debug)和发布版(release
  10. Android(安卓)打开PDF,PPT,WORD,EXCEL,CH