null object pattern unable to solve the problem of multiple return types

38 views Asked by At

Sometimes users prefer not to disclose marital status, which is fine in my domain. So I have data where user is either married or not and I have data where I don't know the status. My goal is to make sure the function for marital status check as below returns only single type of data. Although I am using php but I am sure this applies to any language out there.

This is the interface

interface MaritalStatusInterface
{
    public function status(): ?bool;
}

This means status can return true or false and in some cases null. This was my implementation.

class MaritalStatus implements MaritalStatusInterface
{
    const SINGLE  = 0;
    const MARRIED = 1;

    private $status;

    public function __construct(int $status)
    {
        if($status !== self::SINGLE && $status !== self::MARRIED)
        {
            throw new \InvalidArgumentException("Given marital status '$status' is invalid. Marital status should be either single as " . self::SINGLE . " or married as " . self::MARRIED, 7263);
        }
        $this->status = $status;
    }

    public function status(): ?bool
    {
        return ($this->status)?true:false;
    }
}

Now this is the null object when I am unable to get marital status data.

class NullMaritalStatus implements MaritalStatusInterface
{

    private $status;

    public function __construct()
    {
        $this->status = null;
    }

    public function status(): ?bool
    {
        return $this->status;
    }
}

My question is I am unable to split the return type of Null object and real object status function. The primary benefit as per my understanding for using null object pattern is functions are more predictable as if it is bool return type then it will always return bool.

How can I refactor my code so that the function

public function status(): ?bool

can be written as

# for MaritalStatus class

public function status(): bool

and

# for NullMaritalStatus class

public function status(): null

Is it even possible? Surely that will not conform to MaritalStatusInterface. I am not sure if using multiple interfaces can solve it. Or am I looking it in a totally wrong manner and there is nothing wrong in having nullable return types?

0

There are 0 answers