策略模式在Android中的应用


一 什么是策略模式

设计模式是人们在解决软件开发过程中总结出来的智慧结晶。策略模式也是一种解决实际问题的技巧。
在讲策略模式之前,我们先来研究一下三国时期 一个励志小军阀的故事。


公元2世纪,你来到了三国乱世,作为一名割据了一个县城的初级军阀,正面对着与隔壁军阀老王的一场艰难决战。
双方的作战人数都达到了上千人,而你作为军事首领,十分紧张的策划着战争的各个细节: 粮草供应、情报收集、敌人策反,军心士气、作战方略 等。
战场局势,瞬息万变,而你必须小心而严谨地操作这一切。


在另外一个平行时空内。
另外一个二十一世纪的你,作为一个初级的Android程序员,今天的工作内容是去绘制一幅五分钟K线图。这个功能模块的需求是:通过获取到的股票数据,将其按照规则绘制到UI组件上。
包括:
以蜡烛线的形式绘制出每五分钟的 股票涨跌情况,开盘价,收盘价、
以柔和曲线的方式绘制出M5-M10数据、
支持用户手动缩放,动态计算时间单元。
根据当前选择区域,动态绘制坐标轴等功能

具体效果参考这个。 https://github.com/zmobs/DoChart





好,老天眷顾。

你在与老王的战争中大获全胜。现在你成为了统治了一个州的中等军阀,具体参考 孙坚,公孙瓒

此时的你已经是三国有头有脸的人物了,自然不能事必躬亲。但是军事事务却更加繁忙了。甚至可能同时要面对好几场战争。
比如孙坚,他虽然不在前线亲自作战,但是为了自己的身家性命和荣华富贵。他在每天的作战会议上都会对手下坐镇各地的四员大将 :程普,黄盖,韩当,祖茂 严加叮嘱:

首先要高举xxx理论,xxx思想,坚持听xx指挥 等重要问题。
其次要做好 粮草供应、情报收集、敌人策反,军心士气、作战方略等工作。

而另外一个平行空间内的你,因为任务完成的很好,现在要开始完全负责股票行情K线部分的绘制工作了。
炒股,或者了解股票业务的同学都知道,K线的业务主要包括这么几个方面。


分时图,分钟K线图,五日K线图,月K线图
效果类似:




虽然各自的展示和计算方式存在差异,但是其中最核心的部分依然很类似:
以蜡烛线的形式绘制出每五分钟的 股票涨跌情况,开盘价,收盘价、
以柔和曲线的方式绘制出M5-M10数据、
支持用户手动缩放,动态计算时间单元。
根据当前选择区域,动态绘制坐标轴等功能






好。上天再一次眷顾了你。

你打败了周边的其他军阀,成功的割据一方,改朝换代。三分天下。

首先,恭喜你做了皇帝,但是战争依然存在,居安思危实在是这个乱世中生存下去的重要原则。
作为最高领导,你依然叮嘱和监督着手下,以及手下的手下做好:
粮草供应、情报收集、敌人策反,军心士气、作战方略等。

这样才能去自信应对每一场战争。


而已经成为高级程序员的你,要完成股票行情部分的整体功能。
不仅仅包括K线的绘制,还包括各种通用的证券指标甚至很多自定义指标。 比如 MACD,VOL指标。 这些都要有各自的特定的展现方式:

VOL 要讲成交量以柱状图的形式展示。
MACD 需要以曲线展示EMA12,以上下对称变色块展示DEA
等等等等 无穷无尽。

效果参考




这要是每个实现都以一个组件的形式实现,不仅自己累死了。而且代码也大大的耦合在了一起。后续是没法维护了。

但是机智如你,成功的发现这些需求之间还是有共性可循的:

1 业务图形绘制
2 手势点击识别
3 坐标区域选定及动态更新。

于是策略模式营运而生。





二 策略模式有什么好处。

省心,省心,省心。 还是省心。

策略模式更多是系统解构上的优化,并非运行效率上的提升。

做皇帝的你,不需要费心了解手下的上百位将领的方方面面,我不管你长的丑不丑,也不关心你人品好不好。
我只关心你能否做到以上几点,把战争打赢。

作为程序员的你,讲一个复杂的模块,进行了块状切分。
本来要写十几次的界面组件通过拆分功能,实现了良好的扩展性和解耦合效果。
今后就算要实现其他什么乱七八糟的指标都可以通过集成策略接口,完美的扩展。








三 策略模式的使用场景:


策略模式 义一系列的算法,把每一个算法封装起来, 并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。 也称为政策模式(Policy) 。( Define a family of algorithms , encapsulate each one , and make them interchangeable . Strategy lets the algorithmvary independently from clients that use it. 



上面这段是摘自google的一段策略模式解释。 用人话来说就是:应用场景不固定的情况下,核心算法及处理逻辑可以进行封装。从而实现清晰,良好的代码。(个人理解)




代码示例:

这里仅给出 指标策略的接口代码,具体请参考github DoChart项目。

重点是 StockIndexView类

package com.dqqdo.dochart.ui.view.index;

import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.RectF;

import com.dqqdo.dochart.ui.view.stock.CandleBean;

import java.util.ArrayList;
import java.util.List;


/**
 * 作者:duqingquan
 * 时间:2017/7/21 17:04
 */
public abstract class IndexStrategy {

    // 数据集合
    ArrayList<CandleBean> candles;


    /**
     * 设置集合数据
     * @param data 数据集合
     */
    public void setData(ArrayList<CandleBean> data){
        this.candles = data;
    }

    /**
     * 获取数据集合
     * @return 数据集合
     */
    public ArrayList<CandleBean> getData(){
        return candles;
    }


    /**
     * 计算公式关键点
     * @return
     */
    abstract boolean calcFormulaPoint(int startIndex, int endIndex, RectF viewPort);

    /**
     *  获取Y轴描述字符串
     * @return 字符串描述数组
     */
    abstract String[] getDescYStr();

    /**
     * 获取x轴描述文本
     * @return 文本数字
     */
    abstract String[] getDescXStr();

    /**
     * 获取x轴描述文本对应坐标
     * @return x坐标数组
     */
    abstract Float[] getDescX();


    /**
     * 绘制指标数据
     * @param canvas 画板
     * @param paint 画笔
     */
    abstract void drawIndex(Canvas canvas, Paint paint);


    /**
     * 获取指标名称
     * @return 指标名称
     */
    abstract String getIndexName();


    /**
     * 获取指标公式
     * @return 指标公式
     */
    abstract String getIndexFormula();

    /**
     * 获取选中的指标
     * @return
     */
    abstract int getSelectIndex(PointF pointF);


    abstract void drawSelectIndex(Canvas canvas, Paint paint, int index);

}


云笔记地址: http://note.youdao.com/noteshare?id=423f4bcc646170bed153465591543eb2&sub=DB1DB6DAED2E40668F63E18F3245AE9F
源码地址: https://github.com/zmobs/DoChart



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值