Anyone that is a regular reader here knows that I am a huge fan of interfaces, type hinting and polymorphism. Interfaces are one of the harder concepts in object oriented programming, and object oriented PHP in particular. But as much a fan as I am of interfaces, the truth is that sometimes you can go overboard with interfaces.
Some objects don’t need a common interface.
We like to imagine that our object oriented code follows all the great things that we know object oriented programming should be: it’s testable, extendable, reusable. But the honest truth is that some objects will never have a peer; there will never be another object that implements the same interface but behaves differently.
Interfaces exist for objects that do the same job in different ways.
Where interfaces truly shine is when they’re used for an object that performs a specific task, but does it differently from another object that performs the same specific task. For example, a caching interface can inform your application how to cache data, abstracting away the specifics of Memcached, APC or other caching mechanisms you might choose to utilize.
Objects that aren’t meant for reuse shouldn’t have interfaces.
Sometimes your objects aren’t designed to be reused. If that’s the case, there’s no logical reason why they should implement an interface.
A controller, for example, doesn’t have an interface. You’ll never re-implement a specific controller type in a different way. Or take the value object: having it implement an interface doesn’t make sense because the value object won’t ever be implemented any other way.
What about interfaces and testing?
Interfaces are tremendously useful for testing since they can be implemented easily as mock objects. But for concrete classes that have no dependencies there’s no reason not to use the object; moreover, PHPUnit’s getMock() method can imitate any object you might need to inject or work with. This allows you to test those one-off objects that don’t have interfaces without having to worry about the dependencies they introduce.
Type hinting on concrete classes is okay
It’s perfectly reasonable to type hint on concrete classes like value objects. This is because you actually do want an instance of that particular object. There’s no reason to create an interface for the implementation of a type hint.
Interfaces are a tool, but not a universal tool.
I’ll still continue to write interfaces, and encourage others to do so. They’re a great tool for reuse. But they are not a required tool, and they’re not a universal tool that should be applied all the time. Interfaces should be implemented when they solve a specific problem, and left out when they don’t, just like every other object oriented concept.
Frustrated with your company’s development practices?
You don't have to be!
No matter what the issues are, they can be fixed. You can begin to shed light on these issues with my handy checklist.
Plus, I'll help you with strategies to approach the issues at the organization level and "punch above your weight."