Instead of a Null Object, you should go all-the-way and just use a monoid.
That way you won't have the tonally weird situation described above when you have a NullSaiyan and a Saiyan type in your hierarchy, but you'll gain the benefits of the Null Object Pattern...
To me, seeing a Maybe Saiyan (which can either be a Saiyan or None) makes more contextual sense, as I know this is an object that can be one or the other.
It also allows me to create things like:
/* * Adds two Maybe Point objects into a list. */funOption<Point>.plus(element:Option<Point>)=this.fold(ifEmpty={element.map(::listOf)},ifSome={a->element.fold(ifEmpty={listOf(a)},ifSome={b->listOf(a,b)}).some()})
Using a monoid lets you move the definition to the handler functions instead of providing you with a place to hide functionality away to surprise later consumers.
The whole idea of the pattern is to let the client not know whether it is dealing with actual objects or nulls. It is usually used with "for-each"s and it is yet another case of polymorphism.
Your idea sounds good if you wanted to let the client decide what to do on each type, which is not the use case of this pattern.
Of course, different scenarios require different approaches.
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
Instead of a Null Object, you should go all-the-way and just use a monoid.
That way you won't have the tonally weird situation described above when you have a
NullSaiyan
and aSaiyan
type in your hierarchy, but you'll gain the benefits of the Null Object Pattern...To me, seeing a
Maybe Saiyan
(which can either be a Saiyan or None) makes more contextual sense, as I know this is an object that can be one or the other.It also allows me to create things like:
Using a monoid lets you move the definition to the handler functions instead of providing you with a place to hide functionality away to surprise later consumers.
The whole idea of the pattern is to let the client not know whether it is dealing with actual objects or nulls. It is usually used with "for-each"s and it is yet another case of polymorphism.
Your idea sounds good if you wanted to let the client decide what to do on each type, which is not the use case of this pattern.
Of course, different scenarios require different approaches.