Constantine
Constantine

Reputation: 510

Interface method argument without a type - code smell?

I'm thinking about creating an interface method with an argument that can have a mixed type, to act like metadata. I don't know the metadata type upfront, but I know that some kind of it (or something like context) may be required by the external system adapter implementation.

Example in PHP:

interface AdapterInterface
{
    public function someMethod(SomeEntity $entity, mixed $metadata = null): void;
}

class ExternalSystemAdapter implements AdapterInterface
{
    public function someMethod(SomeEntity $entity, mixed $metadata = null): void
    {
        if (! $metadata instanceof MetadataThatAdapterIsAwareOf) {
            throw new Exception('Invalid metadata');
        }

        // do stuff
    }
}

class Service
{
    public function __construct(private readonly AdapterInterface $adapter)
    {
    }

    public function doSomethingWithEntity(SomeEntity $entity, mixed $metadata)
    {
        return $this->adapter->someMethod($entity, $metadata);
    }
}

$service = new Service(new ExternalSystemAdapter());
$service->doSomethingWithEntity(new SomeEntity(), new SomeMeta());

Is this a code smell? Can it be avoided somehow?

Upvotes: 0

Views: 128

Answers (1)

nik0x1
nik0x1

Reputation: 1461

Using instanceof in code is a potential place of violation of the open-closed principle (OCP). When a new type appears, you will have to write an additional if, thereby changing the ExternalSystemAdapter class.

A possible solution could be to define a MetaData interface and its various implementations. Moreover, adding new implementations in this case will not affect the ExternalSystemAdapter class.

Upvotes: 0

Related Questions