寻找android中的设计模式(二)
来源:互联网 发布:淘宝家具沙发 编辑:程序博客网 时间:2024/05/01 06:59
寻找android中的设计模式(二)
概述
前面学习了单例模式和观察者模式,其中观察者模式可以很好的降低对象直接的耦合。后面的模式会接触到更多的设计原则。
寻找策略模式
定义:定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
学完之后,我也思考着生活当中哪些地方可以使用到。就以游戏为例吧,需求描述是:有很多个英雄,每个英雄都有自己的技能和坐骑。用户可以随意定制英雄的技能和坐骑。
根据策略模式,我们先把会变化的技能和坐骑抽出来,定义两个接口:
public interface IAttackBehavior {public void attack();}
public interface IMountBehavior {public void mount();}
根据接口实现现有的几个算法,也就是各种技能和坐骑。简单举几个:
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("飞行坐骑");}}
有了不同的算法,我们定义一个英雄的父类,将技能和坐骑组合进来。
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();}}
这样就可以给英雄设置不同的技能和坐骑。
实现几个英雄(客户)
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;}}
可以看到客户(英雄)和算法(技能和坐骑)完全独立。
测试
public static void main(String[] args) {Hero heroA = new HeroA("英雄A");heroA.setAttackBehavior(new FireAttack()).setMountBehavior(new AirMount());heroA.attack();heroA.mount();}
打印结果:
英雄A火攻击飞行坐骑
该模式的好处是当需要增加一种算法(技能)可以任意添加。而且可以很方便的给客户(英雄)定制算法(技能)。
接着寻找android源码中的该模式:
动画插值器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插值器(先加速后减速)。我们可以给客户设置不同的插值器(DecelerateInterpolator、Acceleratelnterpolator等);
从动画插值器的设计来分析,它封装了变化即将各种算法(插值器)独立起来,将插值器组合进来没有用继承。对于ValueAnimator只针对客户,不针对插值器的算法,符合针对接口编程,不针对实现编程。
列表适配器
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原则如下:
封装变化
多用组合,少用继承
针对接口编程,不针对实现编程
为交互对象之间的松耦合设计而努力
类应该对扩展开发,对修改关闭
依赖抽象,不要依赖具体类
- 寻找android中的设计模式(二)
- 寻找android中的设计模式(一)
- 寻找android中的设计模式(三)
- Android设计模式(二)
- Android系统设计中的设计模式分析之二
- Android设计模式(二)- Builder模式
- Swift中的iOS设计模式(二)
- spring中的设计模式(二)
- Spring框架中的设计模式(二)
- android 中的设计模式
- Android中的设计模式
- Android中的设计模式
- android中的设计模式
- Android中的设计模式
- Android中的设计模式
- Android中的设计模式
- Android中的设计模式
- android中的设计模式
- visio2013提示“安装程序找不到office.zh-cn\branding.xml。请浏览确定有效的安装源,然后单击确定”
- android 百度地图路径规划问题(第一篇)
- Oracle server和client安装配置
- 数字图象处理——仿射变换
- 子网掩码、子网号和主机地址
- 寻找android中的设计模式(二)
- 中国SSL证书市场份额,沃通WoSign排名第一
- 简析Android的垃圾回收与内存泄露
- 检测点是否在扇形之内
- unity打包文件夹成zip格式(包括文件夹和子文件夹下的所有文件)
- matlab在一阶动态电路时域分析的应用
- Human Resource - Presentation
- 运用link query特性query自己的Scope中department或其它scope中的department
- leetcode Median of Two Sorted Arrays