Is it bad practice to use empty interfaces?

Asked

Viewed 418 times

23

I have heard comments that it would be a good idea, when a future implementation can take place.

Also heard that it is a bad practice.

I know that in PHP, for example, there is an interface called Traversable, which has nothing. It serves only to identify that an object can be used by foreach.

  • It’s a bad practice to use empty interfaces?

  • It is acceptable to do this only to do induction of types, as in the example below?

interface AcceptableInterface {}

class Acceptable implements AcceptableInterface{}

function is_acceptable_class($object)
{
   return ($object instanceof AcceptableInterface);
}


is_acceptable_class(new stdClass); // false
is_acceptable_class(new Acceptable); // true
  • 1

    We should not implement directly Traversable, it is used internally by PHP only: http://3v4l.org/vho4J . You must use Iterator as documented - http://php.net/manual/en/class.traversable.php

  • I quoted Traversable as example of empty interface, but thanks for the information :)

2 answers

24


That’s what I always say, good or bad practices depend on the case. The term, unfortunately, is used to create manuals, "the right way to do," and so people start following things blindly. Everything can be good or bad depending on the context. And the context involves an unimaginable amount of variables, including technical and political aspects, going through the people who are working or will work on the project.

Such good practices have caused more problems than help, since most people follow these "rules" as if they were something they should always do.

So I can tell you that you have no problem doing that if you have a good reason and you know what you’re doing. If you understand the problem you can cause if you do so. And almost everything can cause trouble to a greater or lesser degree. If you don’t know what you’re doing, don’t do it. Don’t start programming seriously if you don’t know as program :)

Marker Interface

What this interface does is mark a class to say something about it. This has a name: Marker interface Pattern.

Interfaces are to indicate that a class has a certain capacity. Hence it is possible to interpret it in two ways: the interface must always tell what capacity it is referring to, that is, it must indicate at least one method that the implementing class must have; or it just needs to indicate something in the class to give semantics.

If you had a big problem or were totally against what the language allows, it would obviously be forbidden to have interfaces with zero members. Since it’s not, you can use it when you see fit.

In certain contexts, that is, in certain teams, or in certain languages, it may be that this is poorly viewed. It may be considered a code Smell. But code Smell is not the same as code Rotten (I think I invented the term :P). It should not be avoided at all costs, otherwise generate another code Smell. It should just be avoided, there’s a difference there.

For example, there are languages that have attributes. In such cases it is better to use this mechanism. In languages that do not have this, the Marker Interface standard can be used as a simulator of the attribute. It has some advantages. Some will say it is abuse, others will say it is more advantageous than the attribute because it can be checked at compile time. But this isn’t worth much to PHP. And you can also check the compile-time attribute with some tool.

But what trouble they cause?

I know of a problem: is that all descendants will have this marker. With the use of the attribute (also called annotation) this does not occur. You may or may not want this.

In PHP, given the philosophy of the language and given the numerous more serious flaws in the language, I would say that it is not a big problem to use it, but not abuse.

It can be used as a documentator. Then I think it’s too much. It needs to have a clear function in the code. Is the code unclear and can’t do better? Use comment.

It can be useful in applications that need to use aspect-oriented programming.

From the conceptual point of view, object-oriented, it is not common to do so. It is said that the interface should have some member.

Completion

We can only talk about recommendations, and as I said, it depends on context. Avoid, but if you really need to, go ahead. I particularly think you can always live without it. But in more complex codes it can be a hand on the wheel if there is no better mechanism.

Before using something you must find a good justification. If you find one, know what you’re doing, use it, but try to find another way first.

It is a pity that the excerpt presented does not give a clear indication of its use. I believe it is being used as a form of reflection and probably some aspect implementation technique (AOP).

  • 1

    I hadn’t thought about this problem: "Every class that inherits the class that implements the empty interface, will 'have' it one way or another"

  • 4

    Good answer (I particularly liked the mention of the pattern Marker). Moreover, from the maintenance point of view (which seems to be the main argument in favor of using empty interfaces implicit in the question), in a future need the implementation of a new interface and its use (implementation) on the part of one or more existing classes is quite trivial. In fact, if it comes to the point that an interface has been missing for a large number (or a large hierarchy) of classes, it has probably been wrong from the start. :)

  • 1

    @Luizvieira no doubt, and if made a great hierarchy probably erred too :P

  • @bigown Ditto. :)

  • @bigown, his reply reminded a colleague of mine: "Everything depends"

  • Great answer, but it seems that the conclusion is based on opinion... S

  • 2

    @Kaduamaral is not enough to be, it is almost. To say that it is taste, it depends, it is something objective. To say that I like this, I think, is pure opinion. You can put a little opinion as long as you have something objective that supports the answer, the opinion needs to be secondary, if it is withdrawn, the answer has to survive.

  • In fact @bigown, it was only at the end even that there was a "taste" of opinion, but opinions of those who understand the subject are generally welcome. + 1

  • 1

    Coining new terms :P, already gives to write a book of good practices or anti-patterns hehe, entitled to a loongo chapter on exceptions :).

  • nor comments if necessary in that reply...

Show 5 more comments

-2

It’s neither a good nor a bad practice, it’s just a practice, the above answer says a lot and I’m just adding mine as an add-on attempt to open your head to other ideas.

As stated, an interface will eventually be propagated to child classes that parent interface is defined, technically speaking, is a bad practice since since the interface in its main role is created to generate a liability contract between Oce and its class, but this does not mean that it is a bad practice, because the interface on the other hand even empty it helps to maintain a certain hemogenicity of your code and helps in the future for the scalability of your interface that enters the SOLID Patterns where the first principle is that every class should have a single responsibility and its interface would help that in the future or at the moment.

And as was said in the above answer this is one of the great sorrows that we have in PHP unfortunately, due to the high dynamism of the language and it has not been built on solid stops it ends up getting all a little weird and even sounding wrong in many ways if we look at the paradigms of object orientation and etc...

And as mentioned above, do you have any reason to do that? If so, okay, but you know what you’re doing?

I came from the C++ crowd so a lot of object-oriented and paradigm-oriented stuff is well rooted in my head and when I see PHP working that way it gives me the creeps.

Now a part more of the professional trajectory in relation to your question:

And even with 8 years of PHP I have never done what you are asking, and it is not because it is wrong or right as was said above, good practices are not absolute truths. I did not because I saw sense, as I said, interfaces are contracts, if you have a contract that even if it extends from some other existing contract then so that you are making a contract intermediary upon one that already exists?

For example, Voce has the x interface that extends some Interator of life, ok, but its x interface is various and Voce has no prospect that it will actually turn some contract in the future. As stated above, every class you inherit from your father will end up inheriting this interface and it can turn from a simple meaningless thing to a brutal headache for you.

Particularly, I have always been the guy oriented to good solutions, where I do the mix between good practices with good solutions, but I never stop favoring good practice on top of the solution, not every code Smells is a code Rotten as was mentioned above and not every go Horse is a code Smells.

Everything will depend on its context and one of the main mottos of object orientation is context, so technically Oce is not wrong, but always in the scalability of its application, think about that code in 10 months and main think if you would like to see it in 10 months like this.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.