Null Object Pattern

后端 未结 6 1694
执笔经年
执笔经年 2020-12-25 13:14

There seems to be a growing community of people saying that you should never return null and should always use the Null Object Pattern instead. I can see the usefullness of

6条回答
  •  悲哀的现实
    2020-12-25 13:57

    MattPutnam's answer is right on point, and I second it. I'd add this: the concept of "null object," when you analyze it, seems to boil down to the mathematical concept of a monoid. You can think of it this way: a monoid is a type that has both of these things:

    1. An "append," "sum" or similar operation, which needs to be associative: a.op(b).op(c) is the same as a.op(b.op(c)).
    2. An "empty," "zero" or "null" value, that acts as the neutral element or identity element of the operation.

    The classic example of the null object pattern is to return an empty list or array instead of null. Well, lists are a monoid, with append as the operation and the empty list as the neutral element.

    Now, the problem that you face in your Car example is that Car isn't really a monoid; there is no notion of "the empty car" or "the neutral car", and there isn't really a sensible operation that you could use to combine two Cars into one.

    So the recommendation you're rightly getting is to use something like the Java 8 Optional. And the trick is that no matter what type T is, Optional is a monoid:

    1. The monoid's "combine" operation is "pick the first value if it's not empty, otherwise pick the second value":
      • x || empty = x
      • empty || x = x
    2. The neutral element is Optional.empty(), because Optional.empty().orElse(anything) is the same as just anything.

    So basically, Optional is a wrapper that adds a null object to types like Car that don't have one. The Optional.orElse(T value) method that is a slightly refactored version of the "pick first non-empty value" monoid.

提交回复
热议问题