Skip to content

Instantly share code, notes, and snippets.

@belden
Created October 29, 2014 18:57
Show Gist options
  • Save belden/44908dbd04858443cf62 to your computer and use it in GitHub Desktop.
Save belden/44908dbd04858443cf62 to your computer and use it in GitHub Desktop.
package Pattern::NullObject;
use strict;
use warnings;
use overload (
'""' => sub { '' },
bool => sub { 0 },
fallback => 1,
);
sub new { return bless [], shift }
sub DESTROY { }
sub AUTOLOAD { shift }
1;
__END__
=head1 NAME
Pattern::NullObject - how I expect the Null Object pattern to work in Perl
=head1 SYNOPSIS
Let's say you have an invoice which can fetch its coupon.
sub get_coupon {
my ($self) = @_;
if ($self->coupon_id) {
return My::Coupon->new(id => $self->coupon_id);
} else {
return undef;
}
}
Any consumer of $invoice->get_coupon needs to check the return value to see if it's undefined:
if (my $coupon = $invoice->get_coupon) {
# ...deal with the coupon somehow
$coupon->apply_to_order($invoice->order);
}
If we use the Null Object pattern in this class, then we can change our Invoice class like so:
sub get_coupon {
my ($self) = @_;
if ($self->coupon_id) {
return Coupon->new(id => $self->coupon_id);
} else {
return Pattern::NullObject->new;
}
}
i.e. instead of returning undef, we'll return a Pattern::NullObject. Now the caller can look like this:
my $coupon = $invoice->get_coupon;
$coupon->apply_to_order($invoice->order);
If we get a real Coupon back, great! it gets applied to the Order. If we get a null coupon back, great! We can still treat it like it's a coupon, but nothing happens.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment