×

Loading...
Ad by
  • 推荐 OXIO 加拿大高速网络,最低月费仅$40. 使用推荐码 RCR37MB 可获得一个月的免费服务
Ad by
  • 推荐 OXIO 加拿大高速网络,最低月费仅$40. 使用推荐码 RCR37MB 可获得一个月的免费服务

节前最后一刻,写点我对Null的思考。

本文发表在 rolia.net 枫下论坛我最近写了一小段的SQL helper。就是帮程序员们在需要的时候拼接SQL代码。Java程序员们如果不用ORM的话,恐怕人人都有这样的烦恼。
在我读了公司里某人写的超过2000多行的String拼接后,我彻底郁闷了,于是终于忍不住把它们改成了下面的样子:
sqlBuilder.priortyUp().query.on("column_name1").value("some value")
.and().query.on("column_name2").value("some value").encoding()
.priortyDown();
这么一来容易读很多,也好看也轻便,一行写完。
但是万一人家给的输入参数是null呢?问题就来了。null.upperCase();膨,炸弹爆炸了。所以我们就必须检查输入的参数不是null。可是你检查了,怎么返回检查结果?链式编程要的就是一路点下去,不会有人来给你检查返回值的。抛异常?那和爆炸有什么两样?所以因为我们有了这个问题,我们的程序员写代码才会变成
boolean success = xxx.aaaa();
if(!success) ......
success = xxx.bbbbb();
if(!success) ......
或者try {....} catch(Exception e) {....} 倒是简单了,但有没有人听说过以前手机开发的时候是不允许用try/catch的?那是巨大的系统开销。

所以我们要的是一个一路到底的方案,不管我点多少个点,你都不要给我错误的返回值,或者异常。最后当我写:run的时候,你才告诉我对不对。这叫做Lazy方式。
那我们就想到,如果就算你给我一个null的东西,这个null的东西也能够接受一系列的操作而不崩溃呢?这就是空对象的作用了。所以当我一读到空对象,我就觉得这就是我多年来在寻找的一个东西。更多精彩文章及讨论,请光临枫下论坛 rolia.net
Report

Replies, comments and Discussions:

  • 工作学习 / 学科技术 / 节前最后一刻,写点我对Null的思考。
    本文发表在 rolia.net 枫下论坛我最近写了一小段的SQL helper。就是帮程序员们在需要的时候拼接SQL代码。Java程序员们如果不用ORM的话,恐怕人人都有这样的烦恼。
    在我读了公司里某人写的超过2000多行的String拼接后,我彻底郁闷了,于是终于忍不住把它们改成了下面的样子:
    sqlBuilder.priortyUp().query.on("column_name1").value("some value")
    .and().query.on("column_name2").value("some value").encoding()
    .priortyDown();
    这么一来容易读很多,也好看也轻便,一行写完。
    但是万一人家给的输入参数是null呢?问题就来了。null.upperCase();膨,炸弹爆炸了。所以我们就必须检查输入的参数不是null。可是你检查了,怎么返回检查结果?链式编程要的就是一路点下去,不会有人来给你检查返回值的。抛异常?那和爆炸有什么两样?所以因为我们有了这个问题,我们的程序员写代码才会变成
    boolean success = xxx.aaaa();
    if(!success) ......
    success = xxx.bbbbb();
    if(!success) ......
    或者try {....} catch(Exception e) {....} 倒是简单了,但有没有人听说过以前手机开发的时候是不允许用try/catch的?那是巨大的系统开销。

    所以我们要的是一个一路到底的方案,不管我点多少个点,你都不要给我错误的返回值,或者异常。最后当我写:run的时候,你才告诉我对不对。这叫做Lazy方式。
    那我们就想到,如果就算你给我一个null的东西,这个null的东西也能够接受一系列的操作而不崩溃呢?这就是空对象的作用了。所以当我一读到空对象,我就觉得这就是我多年来在寻找的一个东西。更多精彩文章及讨论,请光临枫下论坛 rolia.net
    • 同学,思考方向错了,Scala有一种东西叫Try Monad,不然还有Either Monad,一路到底很简单的...
      • 我公司的解决方案。 +1
        Consider this code:
        var aList = getAListOfStrings()
        if(aList.get(0).isEmpty()) {
        print("The first string is empty")
        }
        This code can cause a NullPointerException if either the list or the first string in the list is null. We can address this by using the null-safe invocation operator ?.:

        var aList = getAListOfStrings()
        if(aList?.get(0)?.isEmpty()) {
        print("The first string is empty")
        }
        The null safe invocation operator works on both methods and properties.
        • Java的解决方案。
      • Try[T]是一种对错误的处理办法。
        当然是很优雅的处理,但是还是一种故意为之的处理。和我想法并不完全一样。如果某程序员忘记处理了呢?实际上我们大量的bug其实都出自于此。要有一种自动的方法来处理才行。

        当然,scala我也是新学。我猜想是将所有的None都隐式转换成某个class的null实现。在这个SomeClass_None extends SomeClass中,忽略掉所有的操作而不出exception.
        • 我说你们几个,今天有加班费吗?
          开玩笑啦,Merry Christmas
          • 嗯嗯,算法当酒,Merry Christmas.
        • 巨汗……你把Nothing 和 None两个都混在一起了,None只对应Option Monad, Nothing 才是对应所有的类型做Bottom type
          • 另外,咱别说这些了,type system和side effect 这个课题一堆phd在搞,不是这个生蛋快乐的时节应该思考的东西
            • 人家喝咖啡的时候我在学东西,相信不久就能赶上的。 +1
    • 现在的C都可以做到不担心空指针了,所以你就别思考这个问题了。
    • 绝大多数情况,抛异常比run的时候出错好太多了。有可能你会遇到try/catch的开销也要考虑的情况,但是当你用复杂的系统设计去解决的时候,很快你会发现平台升级了,而你的系统却很难简化了。 +1
      • try/catch当然也是好的
        关键是某些人会忘记try/catch。我最近就修了个bug,程序崩溃了,我dig了5层调用下去,发现是有一个自定义的exception,偏偏这个自定义的还是继承了runtimeException。于是编译器不会报错。上面五层的程序员在调用这个函数的时候怎么也想不到还需要catch一下。我觉得当然不能怪他。最后当然这个异常被总的try/catch抓住了,主线程未崩溃,但这个任务无论如何是failed。这个处理只能算应急,不能说是优雅吧。一直在想怎么避免这种情况发生。我还是不怎么喜欢随便乱抛exception的做法
    • 掩耳盗铃 +1
      程序都会有错误。出错了,应该用返回值,错误码或者异常捕捉错误,并及时作处理

      作为一个经常要维护很多代码的开发者,我最恨这种 “一行写完”风格的程序,一旦哪里有错,查找起来特别费劲
      • 你没看懂我的意思。 +1
        你最恨。。。恨完了你做啥?啥也不做,还是那样继续地过日子。

        你最恨的那些程序员,也许是程序员的大多数。他们就是会写那样的代码,就是会不检查null,就是会不写出错信息。那你怎么办?继续骂?

        我们只是想用一种办法,就算你不检查null,就算你没写错误信息。我用一种方法来帮你检查,我用一种方法来帮你写出错信息。你比如上面讲的TRY Monad,就是一种办法。那他这个函数写完,你随便怎么调用它,都不会出错。都会记录下出错信息。那你觉得这有没有意义呢?