《再论语法糖》的现实意义

前些日子问了透明一个天真的问题,透明亲自授道解惑后受宠若惊。SICP这本书我也买了好久了,只不过刚刚看到第二章。正所谓:书非借不能读也。其实我还准备问"那么是否可以把所有Stateful的过程形式化的转变为Stateless的过程",又觉得这个问题太大了,下面就谈一点自己这方面的体会。

再论语法糖这篇Blog的现实意义是什么呢?就是尽量避免写出Stateful的代码,因为Stateless的代码最不容易出错,便于测试,维护成本低,而且更加容易抽象。在实践中可以发现,大部分过程都可以是Stateless的。

  1. 每次声明一个Setter方法时都要拷问自己,是否会使对象变得Stateful,付出这样的代价是否值得,能否通过Constructor注入。如果对象创建以后没有这个属性,这个对象存在是否有意义。
    其实Sping在这方面没有做出好榜样,他鼓励setter注入的方式注定了这个class是Stateful的。Martin Follower 也提过这个问题,鼓励大家通过Constructor注入。
  2. 再进一步,可以问问自己是否连Constructor都可以不要,直接在方法中传入。举个实际中的例子,一个分页类:

    1)Stateful的分页类
    public class PageNavigator {

    private int perPage; // 每页能够显示几项,通过实例变量避免重复传入这个值。

    public PageNavigator(int num) {
    perPage = num;
    }
    /**
    * 返回第pageNum页的数据
    * @param pageNum 第几页
    * @param data 数据集
    * @return 第pageNum页的数据
    */
    public List getPage(int pageNum, DataSet data){
    return data.getResultSet(pageNum*perPage, pageNum*(perPage+1));
    }
    }

    2)另外一种实现就可以避免Stateful的出现
    public class PageNavigator {
    /**
    * 返回第pageNum页的数据
    * @param pageNum 第几页
    * @param data 数据集
    * @param perPage 每页显示几行
    * @return 第pageNum页的数据
    */
    public List getPage(int pageNum, DataSet data, int perPage){
    return data.getResultSet(pageNum*perPage, pageNum*(perPage+1));
    }
    }

    那会有人问,如果采用第二种实现,每次调用都要perPage参数,如果每次perPage的值都一样,岂不是要重复很多次?很简单,再写一个方法就是了,比如每页显示20行的调用发生了许多次:

    private static final int PER_PAGE = 20;
    public List getPage(int pageNum, DataSet data){
    return getPage(pageNum,data, PER_PAGE);
    }


再举一个实际的例子,Struts 的Action需要程序员考虑线程安全,而WebWork的不用,就是因为每次请求过程WebWork创建了一个新的Action实例,虽然这个实例不是Stateless的,但是对于每一次Web调用,它确实是Stateless的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值