First of all I'm developing a parser for an XML-based format for 3D graphics called XGL. But this question can be applied to any situation when you have fields in your class that are optional i.e. the value of this field can be missing.
As I was taking a Scala course on coursera there was an interesting pattern when you create an abstract class with all the methods you need and then create a normal fully functional subclass and an "empty" singleton subclass that always returns false
for isEmpty
method and throws exceptions for the other ones.
So my question is: is it better to just assign null
if the optional field's value is missing or make a hierarchy described above and assign it an empty singleton implementation?
-
1You're referring to the Null Object Pattern: en.wikipedia.org/wiki/Null_Object_patternvaughandroid– vaughandroid2012年11月23日 09:45:22 +00:00Commented Nov 23, 2012 at 9:45
2 Answers 2
I also attended the same Scala course and I agree with e-i-s that you should use the Option[T]
type for implementing an optional field. Here are some more ideas.
The pattern involving
- a trait with method
isEmpty
- several classes or objects extending the trait
- a unique object whose method
isEmpty
always returnstrue
is also used to implement sequence-like immutable structures such as lists, streams, and so on.
Compare:
- An
Option[T]
type containing the valuesSome(t)
, for each valuet
inT
, and the additional valueNone
. - A
List[T]
type containing objects built from two subclasses (and their respective constructors)Cons[T](h: T, t: List[T])
andNil
: these represent immutable lists whose elements have typeT
. Note that here the methodNil.isEmpty
returns true.
None
indicates the absence of a value, while Nil
indicates an empty list.
So an optional value None
is not the same as an empty list Nil
.
NOTE
If you need to test if an optional value is defined or not you can use the isEmpty
method of the Option
type, or pattern matching:
class MyClass(f: Option[String])
{
val field = f
}
and then, to test if the field of an instance obj
of MyClass
is defined:
if (obj.field.isEmpty)
{
}
else
{
}
or
obj.field match
{
case Some(s) => /* do something with s */
case None => /* ... */
}
If your implementation is in Scala, it is idiomatic to use the Option[T]
type.
-
1Wow, that's really helpful. I'm also using this code from java app. How will java work with
Option[T]
? Should I provide some additional methods? Because with null it's simple:if (object.field() != null) {...}
Uko– Uko2012年11月23日 10:03:49 +00:00Commented Nov 23, 2012 at 10:03 -
1I'm not sure, but I think you can call Option's
isEmpty
from Java to check if there's any value (the equivalent toif (object.field() == null) { ... }
). But I haven't tried this.MisterMetaphor– MisterMetaphor2012年11月23日 10:25:51 +00:00Commented Nov 23, 2012 at 10:25 -
2Using Option core methods isEmpty()/isDefined() and get() works perfectly fine from Java.David Pierre– David Pierre2012年11月23日 10:50:58 +00:00Commented Nov 23, 2012 at 10:50
-
And you have
Option.option2Iterable
, so you can useOption
s in enhanced for-loops.Landei– Landei2012年11月23日 14:44:17 +00:00Commented Nov 23, 2012 at 14:44