程序员的上帝视角(4)——视角

对于开发人员来说,工作都是从评估一个需求开始。我们第一个要解决的问题就是看待需求的视角。视角的不同,得到的设计方案可能是完全不同的。作为一个程序员,不能单单从个人视角来看待问题。而是要尝试从不同角色出发,不停思考。

上图是出自一个数据平台7日留存功能。在该原型图中,计算了每天的留存率,并以趋势图的形式呈现出来。常规服务端数据结构定义可能如下:

class RetainRatio {
    /**
     * 日期
     */
    private String day;
    /**
     * 留存比例
     */
    private double ratio;
}

RetainRatio代表了留存的数据结构,其中day为日期;ratio为留存率。服务端将数据封装为List<RetainRatio>结构,传递给客户端,由客户端进行展现。

乍看起来没有问题,但是,对于数据平台,可能存在着大量的其他图形分析的需求,如下图是一个行为按日期统计次数的趋势图。

class EventCount {
    /**
     * 日期
     */
    private String day;
    /**
     *次数
     */
    private Integer count;
}

很明显,当整个系统中存在着大量画像分析时,将会出现非常多的数据结构定义。我们再来考虑一下,如此多的定义,带来的程序复杂度。

  • 对于服务端开发人员,定义大量数据结构,来承载不同的趋势图结构。

  • 对于客户端开发人员,需要理解不同数据结构,并使用不同的代码来渲染和展现UI效果。

程序设计者往往站在数据结构的角度来看待问题,那么,我们从客户端开发人员的角度进行思考。他们根本不想关注数据结构中的day、ratio、count等。而只关注如何将趋势图展现出来。他们唯一需要的就是横坐标和纵坐标。而具体字段的含义,于客户端代码的编写并没有太大关系。

本着解决一类问题,而不是解决一个问题的思路。我们试着将数据结构定义为如下形式:

public class TrendLine {
    /**
     * 名称
     */
    private String name;
    /**
     * 曲线上的所有点
     */
    private List<TrendPoint> pointList;
}
class TrendPoint {
    /**
     * 纵坐标的值
     */
    private double verticalVal;
    /**
     * 横坐标的值
     */
    private String horizontalVal;
}

TreadLine代表了一条趋势线,趋势线上有若干个点List<TrendPoint>;而每个TrendPoint中含有横坐标(horizontalVal)和纵坐标(verticalVal)。

如此一来,暴露给客户端的数据含义就变为了:线——点——横纵坐标,三个概念。那么整个系统中,所有类似趋势图的图表,均可利用这一结构进行封装。

我们再来看程序的复杂度:

  • 服务端多中数据结构定义统一为一种,在计算时,均向该结构统一。

  • 客户端不再理解具体的业务意义(天、行为、留存率等等),仅仅理解:线——点——坐标三个概念。UI展示时的代码,也只会有一份。

我们可以将这一思路,提升为“视角”这一概念。系统设计者在设计时,需要综合考量各个角色视角所关注的东西。

  • 服务端,关注数据计算。

  • 客户端,关注展示,而并不想关注具体业务是什么——例如本例中的天,次数,留存率,行为等等。

  • 测试端,只关注计算和展示的结果是否正确,更加不会关注具体数据结构如何封装。

换句话说,上游向下游暴露什么数据,直接决定了下游理解的复杂度。上游向下游暴露的信息,在保证足够的情况下,应该是尽量收敛,而非无限扩散的。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值