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.
2008-11-05 at 16:13
Do you have much experience in other programming languages? Namely C/C++, C#, Java? We prefix interfaces with I not because we don’t understand them, but to help along users of our code. I can understand if it a solo project, otherwise I think you’re mistaken. Interfaces ARE meant to force users to implement required methods, as well as assuring they are defined for explicit conversions. Not multiply inheritance, although they do solve some cases if used cleverly. Anyway, back to this gibberish about -not helping readability/usability/bug prevention with coding conventions-. What do you think is the purpose of abstraction, access permissions (private, protected, public), properties (accessors, getters/setters), constants (const correctness)? This kind of stuff is part of the standard in many languages. Required by the most professional programmers in the world. Those are ALL designed to help prevent misuse of code, and prevent bugs. Not to mention encapsulation, and abstraction play a part in this goal. With encapsulation outside users of the class should not be aware of the internal workings of the class, take it for what it is, this way the core can change without dependencies breaking.
Anyway, use I for interface if you distribute your code. You’re just kidding yourself if you don’t. You don’t have to use C for class, because class is the default nowadays (used to be S for struct back in the day).
2008-11-05 at 16:21
I mean’t “with data abstraction outside users” but whatever. I won’t make a dent in how you’ve laid this in your mind. If you’re proposing “Abstract” prefix but not interface, you’re hopeless. Yes, no abstract keyword exists in C++, but neither does interface. How about..
I for Interface C for Class S for Struct A for Abstract
There you go, lol. Joking. You know a good IDE solves all these naming convention problems. Such as Visual Studio, and yet Microsoft’s XNA prefixes I for interfaces.
2008-11-05 at 16:28
For the record.. I only agree with what you’ve said (besides the abstract part, that just goes against your argument). Only because if we had proper IDE’s then we wouldn’t need these descriptors. I think I’ll drop the I from my interfaces for my next project. It’s too bad Camera and Sprite are reserved words in AS3 though >.< (ICamera isn’t :P)
2008-11-05 at 16:29
Proper IDE’s and proper languages (C# forces abstract declaration, so it’s easily viewable, not to mention VS debugging is easier).
2008-11-05 at 16:53
@Joe
What do you think is the purpose of abstraction, access permissions [...]
Do you prefix your public methods with “p”? If not, why not?
2008-11-16 at 22:52
This one is really simple to demonstrate by example. If I am coding to interfaces (as contracts) rather than concrete implementations, the ‘I’ is simply nonsensical. If I’m using dependency injection, it is even more so, since my code will have absolutely no knowledge of the specific instance type. If I have a service class which requires access to a DAO for users and a DAO for orders, and the particular instance of each DAO will be injected into my service class, using the ‘I’ makes no sense. My service depends upon a UserDao and an OrderDao. It doesn’t depend upon an IUserDao and an IOrderDao. Meanwhile, assuming that each DAO has basic CRUD operations via some kind of ORM framework, odds are very good that I have an abstract CrudDao implementation that both dao objects inherit from in order to gain access to basic CRUD functionality via inheritance. So I’ve got AbstractCrudDao in my class hierarchy. Note, the inclusion of ‘Abstract’ in the class name is not an identifier - it is a description. If you really want descriptive interface names, then call your interfaces UserDaoInterface, etc. The ‘I’ serves much the same purpose, but it is a very artificial construct which actually takes away from the intent of an interface - to genericize a contract.
a HibernateUserDao extends AbstractHibernateCrudDao and implement UserDao and will be referred to as a UserDao absolutely everywhere in my code except for where the dependency injection is configured to instantiate a concrete instance.
With IoC, the contract becomes the first class type which all of your other code interacts with, so singling it out as ’special’ via the ‘I’ prefix is pretty much exactly the opposite of intent. If anything, the ‘Hibernate’ and ‘AbstractHibernate’ are the equivalent of the ‘I’ prefix on an interface, but are much more appropriate, marking particular implementations that are mostly beneath the radar of a developer that is merely using the api, since that dev will only interact with the contract. The dev that maintains the API must know about the concrete implementations, but the maintaining dev necessarily must know the details of the api internals, so it makes sense for that dev to utilize what are, effectively, private prefixes in order to label classes.
Going down one layer and looking at the domain model itself makes this even more apparent. Let’s say that for testing’s sake, my domain model is implemented as a set of interfaces with a concrete implementation that is probably (in java, anyway) annotated with information about the storage mapping of the class in question. So I can have a Car which has a Wheel and a Tire, and all of my business logic will interact with Car, Wheel, and Tire objects, or I can have an ICar, and IWheel, and an ITire and have those names scattered throughout my codebase. Since the fact that my app uses a HibernateDao is completely irrelevant to every other layer in my app courtesy of dependency injection, the fact that I am currently passing around hibernate-specific versions of the domain objects which were acquired via that same DAO is also irrelevant. I only care that it adheres to the Car, Wheel, or Tire contract.
So far as I can tell, the only people who still argue that interfaces need prefixes because they are not first-class types are those who either do not yet understand how programming to interfaces is absolutely vital to de-coupling code, or don’t yet understand just how well a framework like Spring can truly isolate each layer of an app from every other so that absolutely no knowledge of the implementation details of one layer is ever visible to any other layer. My application layers never know ANYTHING other than the interfaces that describe the layers they interact with. If I have a cross-cutting concern which demands knowledge of implementation details, then I’ll implement it as an AOP aspect that is injected between layers by the framework without the knowledge of any other involved layer, and again, only the IoC framework will need to know the specifics of the aspect’s implementation, which must necessarily match the implementation details of the layers with which it interacts.
2008-11-17 at 08:42
@ideasculptor
I very much agree that the fundamental problem seems to be that those who think prefixing interfaces with “I” have probably misunderstood their use. Perhaps a related problem is that most programmers have yet to grasp dependency injection too? They live in a world where you create new instances of classes willy-nilly, and in that context it feels wrong (to them) to let interfaces be first-class participants. When you move to dependency injection you notice that most of the things you interact with are actually interface types, and the “I” sticks out like a sore thumb.
Thank you for taking your time, your examples are great and show the issue from a more concrete perspective.