If it would have been Java, I should have implemented a Comparable interface. But why? Polymorphism? Readbility? Or something else? And if it was PHP -- should I create Comparable interface for myself?

So here goes the second part.

My colleague told me that it is a rule of thumb in Java to create an interface for every behavioral aspect of the class. For example, if I wanted to present this object as a string, I should state this behaviour by something like implements Stringable, where in case of PHP Stringable would look like:

interface Stringable
{
public function __toString();
}

Is that really a rule of thumb? What benefits are gained with this approach? And does it worth it in PHP? And in Java?

6 Answers
6

I know nothing of PHP, and don't really mean to answer your question, but the answer to your first part is "Polymorphism" and the second is "No". The other answers here do a good job of explaining it all.

What I wanted to add is that you can use classes instead of interfaces.

At the extreme, you can write an abstract class with all abstract methods that works exactly like an interface. The immediate down side is that any class that extends ("implements") this class can't extend another class, which may be a problem, now or later. On the other hand, you can make one or more of your methods concrete and save work in all the extending (formerly implementing) classes. All your descendant classes (subclasses, subsubclasses, etc.) can be referenced as being of this class, providing all the polymorphism of an interface.

My usual process is to start with an interface, see that I have common code in all the classes that implement it, then turn the interface into a base class and put the common code there. Later, I find myself writing a new class that cannot extend the base class but needs to look like it. (I need the polymorphism.) So I write a new interface just like the old one, have the old one--now the base class--implement it, and change all the places where something is declared to be of the base class type to declaring it as the new interface type. The new class then implements the interface also.

And I'm off to the next interface that becomes a base class that spawns an interface.

Having MyEntity implement Comparable<MyEntity> allows you to use Collections.sort(...), and any other operation that acts on Comparable. From the doc:

Lists (and arrays) of objects that implement this interface can be sorted automatically by Collections.sort (and Arrays.sort). Objects that implement this interface can be used as keys in a sorted map or as elements in a sorted set, without the need to specify a comparator.

Using the MyEntity parameter on Comparable simplifies your compareTo method in that you don't need to do any type checking or casting in your code.

In PHP, you do not have rigid type controls like in Java. So in many cases where you had to use interfaces in Java you can use something like is_callable in PHP. PHP does not have compile-time type enforcement, which means you don't gain as much by defining a lot of interfaces, so I would use an interface in cases where there's a non-trivial functionality behind it. E.g., if you wanted to express a file functionality - having open, close, read, write, etc. - you may want an interface. If however you want just one function having an interface may be an overkill.

Interfaces add a layer of abstraction to your code. (like a seam). It means you can then change concrete implementations in dependent classes without breaking your existing code. Its great for decoupling code and makes things like unit testing feasible.

My colleague told me that it is a rule of thumb in Java to create an
interface for every behavioral aspect of the class.

He is wrong. There are plenty of use cases where there is no point implementing interfaces. Often its better to go with the KISS approach. Interfaces add complexity and for small simple classes/applications it may not be worth it.

You should be using interfaces to achieve something (ie implementing a pattern or for unit testing) just blindly implementing something "because its good" will only lead to code bloat

In my opinion, the main points of interfaces are abstraction and type-safety. Implementing an interface forces you to expose some functionality to others, while other components do not need to know about your specific type and its implementation.

For example, a generic sorting algorithm can expect a list of objects implementing the Comparable interface. This way, the algorithm does not need to know about the implementation detail of entities, list items, or whatever you want to sort. But by definition, items implementing the Comparable interface must provide a certain functionality which the sort algorithm can rely on.

Interfaces are a good way to decrease coupling in your architecture, but you shouldn't overuse them because this can reduce the maintainability and readability of your code due to the level of abstraction. If the functionality of classes implementing an interface is very similar, think about a common base class.

In one of our projects, we have a runtime which can host several services which do whatever they want to do. Because our runtime needs to manage those services, it requires the services to implement the interface IRuntimeService with methods like Start or Stop. This way, the runtime can host and manage every possible service, as long it implements this interface. This example might give you an idea about why interfaces can be very useful.

I'm sorry that I can't tell you much about PHP, because I did not do much OOP there.

The first part of your comment implies that interfaces are a good choice for Strategy pattern, or any other that uses polymorphism, right? I am just trying to structure interface use cases, so Polymorphism is one of them, as @java_mouse mentioned.
–
ZapadloApr 4 '12 at 10:59

From my experience, these are the top points I would go for interfaces during my coding.

- Interfaces can make the code flexible by acting as a contract
between the implementations.

Stringable string =new StringFromMe();

Then, later, if you decide that you want to use a different kind of string (maybe there's another library, with a better kind of string ), you switch your code to:

Stringable string =new OtherKindOfString();

the reason is, for example, if you want to create a list of strings and perform some operation on each one, but you want the list to contain different kinds of Strings. On each string you could do:

**string .toString()**

Or You can pass the both types of strings to a method which takes the common interface type.

dosomething(Stringable string)

This concept is also called as polymorphism.

- Ease of unit testing/ mocking.

For example, Your string needs some data from database to computer the toString ( just assume for the sake of explanation) which makes the code not unit testable. Now you can provide a simple implementation of the string

**Stringable string =new TheDummyStringWithoutDBConnection();**

Then you can go ahead with your unit testing of other parts of the code so the unit tests are not dependent on the database or any other external systems per se.