Architectural Atrocities, part 5: Interfaces in AS3
This is the fifth post in the Architectural Atrocities series and now the time has come to scrutinize ActionScript 3.0. The item of discussion is interfaces and how they are used in the ActionScript 3.0 API:s.
Let me start with an OO-maxim:
If you prefix your interfaces with “I”, you have no idea how to use them
(ok, I made it up myself, but that doesn’t mean that it’s not true)
The ActionScript 3.0 API:s have a few interfaces, in general it’s a good thing, it shows that the Macromedia/Adobe developers actually understand something, which hasn’t been obvious in the past.
The decision to include interfaces in AS2 was probably a manager or marketing executive saying “hey, all the other languages have something called ‘interfaces’, why don’t we?”, and the developers quietly obeyed.
In AS3 it seems that the developers (the new ones, I presume, since it’s unlikely that those responsible for AS2 could even begin to design the AS3 API:s) have a general understanding of object oriented software development and what interfaces are and why they are usable.
The point of this rambling
An interface declares a type. It’s an abstract concept and not connected to any concrete implementation. This is very usable since we can tie our code to an abstract concept and don’t worry about the actual implementation. The actual implementation can later change, but we don’t need to worry since we have only programmed to the abstract concept.
A more common OO-maxim states:
Program to an interface, not an implementation
Programming to interfaces leads to low coupling, which is a good thing for reuse and maintenance. If you don’t belive me, you’re disqualified from making a comment to this post.
The problem with the AS3 API:s is that every single interface I have found is prefixed with “I”. I assume this is in order to make it blindingly obvious that it’s an interface*. Given the explanation above, can you see the problem?
The point finally
If an interface is a type, and you want to program to interfaces, your ActionScript code will be littered with types that start with “I”.
Types are types. It doesn’t matter if they are abstract or concrete, they are types, you shouldn’t distinguish between a type defined by an interface and one defined by an imlementation (a class).
Prefixing with “I” takes interfaces aside and tells us that these are special cases, not abstract types. I read code like this as “This is an IFootballPlayer”, not “this is a football player”. This is wrong, a type represents a concept, not a type name and naming conventions should make it easier for the client programmer to think in this way, not harder.
To prefix interfaces with “I” is to not understand that types declared in interfaces are the types you will use in your code. Classes are just implementation specifics. Interfaces are not a convenience for emulating multiple inheritance, and they are not just a way to guarantee that a bunch of classes have the same methods.
* This is sometimes called Hungarian notation, you usually see it in newbie programmers that haven’t started to belive in the holy type checker.
2007-03-25 at 00:15
[...] as is the convention in the ActionScript API:s I have written about that in an article called Interfaces in AS3, the gist of which is “If you prefix your interfaces with ‘I’, you have no idea [...]
2008-04-11 at 15:58
Have never thought about it this way and I’m somewhat convinced by your argument. Although sometimes I do see the need for it when the interface is less of a type and more an implementation of reusable common functionality:
IBindable for example, just a little help for looking up in the intellisense list.
Good argument though always interested in peoples ideas on improving readability and cohesiveness on code :)
2008-04-13 at 12:34
[...] also have a pet peeve: interface names prefixed with “I”. I’ve written about this before so I won’t go in to the details. It suffices to say that if you prefix your interfaces with [...]
2008-04-21 at 16:50
Is this really that big of a deal? I totally agree with the readability part of it, and I do program to interfaces, but the I doesn’t really throw me off in practice. Anyway, it seems like it would be a bigger crime to start creating interfaces that don’t conform to the standard set by the API.
Have you done one on implicit getters / setters? ugh!
2008-04-21 at 17:01
Let me be more specific about getters and setters. I think it’s similar to what you’re saying about how interfaces should be indistinguishable from classes since they’re both types.
Part of the idea of using an explicit get/set method (e.g. with Java) is that you’re using the exact same syntax for getting a value as you would for performing any other methods. foo.getValue() and foo.setAnotherValue(bar) and foo.reset() all use the same syntax. The result of the method is the only thing you care about. This allows us to take publicly declared properties out of the picture.
It also reinforces the idea that some process could be happening behind the scenes (and not that this is just a pointer to a private field).
With implicit getters and setters, I’m now stuck using () sometimes and not others. Not to mention marking my private variables with an underscore or dollar sign. Ugh.
2008-04-22 at 19:51
Mims:
(first of all sorry for taking so long to approve your comments, I’ve had a flood of spam lately so I’ve had a hard time keeping up)
Re: not such a big deal
Try prefixing all your classes with “C” and see what happens. Would that change how you write your code or design your applications? Can you truthfully say that it wouldn’t change anything?
Re: implicit getters and setters
I’m not sure about this one. I used to agree more or less with your view, especially about the hidden side-effects and that, but I’ve come to change my mind.
I’ve written a bit about getters and setters here: http://blog.iconara.net/2007/03/11/mxmlc-wtf-5/ but I’ve somewhat changed my mind since.
The basic idea in OO (and bear with me now, this is basics and I’m not patronising you, I will get to the point, I just have to build up to it first) is to have objects with internal state and a public interface of actions that that object can perform, i.e. encapsulation. This breaks down when noobs start writing a getX/setX pair for each of their (private) instance variables, and unfortunately it seems like it’s only the minority that don’t do that nowadays. So, given the state of encapsulation in the majority of code examples out there I agree with you, because in that world properties (a.k.a. implicit getters and setters) hide the problem even more. It becomes even harder to spot setters that have side-effects, and sometimes you don’t even know if it’s a property or a public instance variable.
However, if you dream away and just presuppose that things are as they should, that the public interfaces of types don’t do everything they can to break encapsulation, but instead enforce it, then properties aren’t so bad. In that world you know that if you mess with an object it will react, because setting a property is not the same as setting an instance variable, there will be a side-effect, just as there will be for a method call. The only thing that differs is the syntax, you’ve got one syntax for requesting actions to be performed and one for sending data.
I mean, really, the getX/setX convention in Java is more or less exactly the same thing as properties, it’s just a different syntax. If you don’t expect instance variables to be public then a property is just shorthand for setX/getX.
Properties in ActionScript isn’t all good though, one huge problem is with the compiler which doesn’t let you have different access levels for the getter and setter. In theory you can have a public getter and a protected setter, but in practice it never works, the compiler gets confused and complains about ambiguity (see the post I refer to above). This more or less forces you to either break your encapsulation by making both public, or write one getter and one setX method, making the code confusing and ugly.
It may be that I have been lured into liking properties more and more from writing Flex applications. Bindings in Flex is implemented through the compiler re-writing properties to add some side-effects, and couldn’t be implemented as elegantly without them. It could be done with the getX/setX convention in Java, and I’m sure there are examples of that, but it would be different, and not at all as elegant (because, for example, you would in all likelyhood have binding syntax that looked like properties, but getX/setX in the implementation).
This became a post in itself, I realise now… so to round it all off let me say that I’m completely with you on how much it sucks to have to mark all instance variables with an underscore.
2008-07-03 at 17:33
[...] would also like to go on record that I hate the *Impl naming convention. Despite what Theo says, I like my interfaces with I’s. *Impl just seems kludgy and redundant, and it reminds me of [...]
2008-07-30 at 22:41
Do you also dislike the convention of ending your interface names with “able”?
I tend to view an interface more as a contract, rather than a representation of a type; after all, an interface cannot dictate which properties to make publicly accessible. Interfaces take care of the verbs in OOP, but not the nouns. I could certainly see your argument if all abstract classes started with an “A”, but I differ from you in that I do see an interface as a special case.
I’m not saying I couldn’t be persuaded to your way of thinking, just that I’m not there yet :)
2008-08-04 at 14:46
@John
No, I don’t dislike the convention of using “able” for types, I think it’s good. My point is that the name of a type should describe it. Something serializable should be called “Serializable” if it is something serializable or “Command” if it is a command, not “ISerializable” or “ICommand”, because it is not a “i-serializable” or a “i-command”.
When it comes to abstract classes there are two variants: those that provide a basic implementation of an interface, and those that both define the interface and provide a basic implementation of it. In ActionScript and Flex an example of the first type is UIComponent (which is an abstract implementation of IUIComponent) and an example of the second is DisplayObject. In my view something like UIComponent should be called AbstractUIComponent, but something like DisplayObject should be called exactly that (however, legitimate examples of the second variant is quite rare, the first variant is almost always the right way to solve a problem). I will not say more about the second variant, and the rest of this discussion is only about the first.
Why do I think that the “Abstract” prefix is a good idea when “I” for interfaces is not? The reason is that you should always type your objects as the most abstract type possible, which means that for objects that are instances of a class descendant from an abstract class the interface type that that abstract class implements is the most abstract type, never the abstract class type. Prefixing the names of abstract classes with “Abstract” both makes it obvious that the class is abstract (which is hard in languages lacking the abstract keyword), and sets the type apart, making it obvious that it is a special type of type, one that you should think twice about when you use it. This is the same argument that most people use when arguing for prefixing interfaces with “I”, but here I think it is valid. Interface types should not be set apart, because they are not special, abstract types are, because they are only convenience classes and should never be seen (except, obviously, when they are used as parent classes).
I hope that the different meanings of the word “abstract” weren’t too confusing in that last paragraph, it really would have benefited from a diagram. A type can be more or less abstract (meaning, more or less, that it is more or less general), but a class can also be an “abstract class” (which just means that the class provides an abstract, as in not-finished, implementation of something).
You also mention that interfaces “cannot dictate which properties to make publicly accessible”, this isn’t strictly true, in ActionScript and C#, the two languages that I know of that have implicit getters and setters (a.k.a. properties), interfaces can define properties. However, that doesn’t mean that it is necessarily a good idea. It all depends on how you use the feature. It’s always a bad idea to break encapsulation, and defining interfaces that dictate how an implementing class should define its inner workings (e.g. instance variables and such) is not a desirable feature.
I’m not sure if this discussion persuades you further, but I hope that it does. Thanks for your comment.
2008-08-10 at 14:44
Thanks for the thoughtful reply. I do understand your Abstract… vs. I… rationale. I hadn’t ever thought about it that way. I always considered both of them special types, due to viewing them from the subclass’/implementor’s perspective. Looking at them from the outside-in, from the perspective of the class that actually does the instantiation and method calls, the differences between an Abstract class and an Interface type becomes clear. Sorry,that was all horribly articulated, but basically to say that I get your point.
Thanks, also, for the info on the implicit getters and setters; I’ve gone all this time without taking advantage of that functionality for my Interfaces. Very handy!
Anyway, I’ll lose the I on my interfaces in my next AS3 project and see how if it changes the way I structure anything.
2008-08-11 at 08:46
Good to hear that I’ve managed to convert someone.
I wanted to add that there is also one practical argument for not prefixing your interfaces: if you want to refactor and replace a class with a number of classes, perhaps a whole hierarchy of classes, one way is to extract an interface from the first class and let all the new classes implement that interface (another way is of course to let the new classes inherit from the original class, but mindless subclassing will come back and bite you).
If the interface has the same name as the class, no code that previously used the class needs to change. If you insist on prefixing your interfaces with “I”, all the code that just use the class need to change. It doesn’t have to change much, just an “I” needs to be added, but it has to be done.
Let’s illustrate this with an example: say you have a class called Service. So far your application has only needed one kind of Service, but now the requirements have changed and you need to introduce a number of new service types. From the perspective of the code that uses the service it doesn’t matter what kind of service it is as long as it works the way it does now. You extract an interface from the Service class, rename the class to something else and make it implement the new Service interface. Then you create the other service classes, making them all implement the Service interface. The last thing you need to change is the code that instantiates the service, making sure that it instantiates the right kind of service in the right circumstances (this part could probably benefit from being refactored into a factory). If the new interface has the same name as the old class you’re done. If not, you have a couple of fun hours wading through the rest of the code searching and replacing.