Just a quick heads-up– my latest article in the ColdFusion Developers Journal is Why Interfaces in ColdFusion Are Irrelevant which was in the December issue. This article builds on an earlier post I made, and goes a different direction than those professing that CF shouldn’t have interfaces because it shouldn’t turn into Java-light.
About
devnulled is a blog which caters to software development related issues with a pro-unix and open standards slant. devnulled has been featured on Slashdot, Digg, the Indeed Blog, O'Reilly Hacks, and del.icio.us/popular.
Brandon Harper, the author behind devnulled,
is a Software Engineer primarily working with Java but also dabbles in Python, ColdFusion, FreeBSD, and Linux. He's been
programming since age eight, professionally for over ten years, and has been been published in various industry publications and popular websites.
Brandon also enjoys music, photography, politics, command prompts, and things with wheels a wee bit much.
11 Responses
Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.
Brandon just a few notes. I’m mainly with you in general but a few items in the article raised my eyebrows. First, having an abstract class enforce an interface is an option, but only if you only have one interface to implement. If your base class actually needs to implement multiple interfaces, or if the same interface needs to be applied to multiple sets of objects, then this won’t work.
Second, Vince did enlighten me somewhat about how interfaces work in BD (and how I assume they’d work in CFMX 8 if they are added). The error is indeed a runtime error. However, the error is thrown at object creation and not when you try to invoke an undefined method as it is now. The difference is subtle but it means that you’re guaranteed to get an error when you test rather than hoping that you get an error at some point when some code calls an undefined method.
As I’ve said, even though I think the time needed to make this work in CF8 would be better spent on other features, IF interfaces are added I will use them. The benefit isn’t huge but there is definitely a benefit.
Hi Brandon,
In the example in the article, should’t the CFCOMPONENT tag of Bar.cfc include the EXTENDS=”Foo” attribute? Otherwise, what’s the point of Foo?
If so, then there’s a limitation of of your pseudo-interface technique: CFML only support single inheritance. Therefore, you can’t have a CFC implement multiple interfaces, nor can you have a class both extend a concrete (non-interface) CFC and also implement one or more interfaces.
The implementation of interfaces in BlueDragon 7.0 allows a CFC to implement multiple interfaces, and allows a CFC to extend a concrete CFC and also implement one or more interfaces.
Vince
Brandon,
I do agree with your conclusion that interfaces in CF are basically pointless (aside from the sound advice to depend on interfaces, not implementations), but I’m not sure I agree with how you arrived there.
You mention a couple of times that “the main purpose of an interface is to ensure that an object follows a contract.” For me, the main purpose of an interface is to allow a pseudo-multiple inheritance – basically, you get the benefits of substitutability without the benefits of reusability. In that regard, it is pointless to have interfaces, since we already have the benefit of reusability for multiple inheritance via mixin, and we have no use for substitutability since we are dynamically typed (unless, someone makes the (in my opinion) mistake of typing the arguments to their functions).
Brian:
Good point about the error being thrown anytime you access the component rather than when you call a particular missing method. I think my only counterpoint that I could make to that would be that you should in theory catch this sort of exception with proper unit and integration testing, but there isn’t such a thing as perfect code or testing either.
I can’t say I would /never/ use them if they were there, but at the same time at a macro/theory level I don’t feel that there is really an optimal way to implement them within a language which isn’t type checked. Overall, I personally think that adding interfaces to a dynamic language is a very slippery slope for a lot of reasons.
Vince:
Yep you’re right, it looks like the extends attribute was unintentionally omitted while I was reformatting the source code for print. Good catch. I need to go back and fix that in the blog entry as well.
I also concur with not being able to do multiple inheritance. Personally I’ve never been stifled in ColdFusion by not being able to do multiple inheritance, and you can always do the ColdFusion version of mixins instead. I guess I haven’t seen much chatter about people bemoaning CFC’s because they don’t support it, but I’m sure someone wishes it were around.
I know that Python has some sort of limited support of multiple inheritance and I believe mixins are also the answer in Ruby– do you know if there are there any other dynamic languages beyond these which properly support multiple inheritance? I’m actually kind of curious about that. Multiple inheritance has always struck me as something that you shouldn’t use very often, and when you do, you’d better know what you’re doing for sure.
Sam:
Just read your comment after replying to Vince– looks like we agree on the point of mixins covering multiple inheritance.
Overall the point of the article is that I wanted to cover the technical side of why I don’t think interfaces are a good idea since I hadn’t seen anyone else mention it (at the runtime implementation level), and it’s one of many reasons why I’m against their implementation. I do still think the primary reason for interfaces is for contracts, but yes, they do also allow multiple inheritance.
Brandon: your arguments against interfaces can be used to argue against the complete implementation of CFCs in CFML. All of the features that classes provide in other object-oriented languages–encapsulation, type safety, etc.–can be easily defeated in CFCs due to the dynamic nature of CFML.
I can easily take the most important sentence of your summary and simply replace “interfaces” with “classes” and it’s the same argument:
“Any implementation of (classes) in the CFML language would essentially only represent a difference in semantics to other ways already available to implement (class)-like objects without providing the (encapsulation, type-safety, etc.) that (classes) should provide.”
This was the point of my blog entry from a while ago entitled, “Is CFML already Java-lite?”, a point that almost everyone missed: every argument against interfaces is essentially an argument against CFCs in general. If you reject interfaces, then you should reject CFCs for the same reasons. Otherwise, you’re simply drawing an arbitray line.
Vince:
My specific point in the article is that the main advantage of interfaces is being able to check and ensure that contracts are followed at compile time rather than runtime. This is technically infeasible within a dynamic language. It’s going to only throw the error at runtime no matter how you bake the implementation of interfaces.
The other counter arguments about interface support which were not covered in my article (on purpose) also can already be done. IE– multi inheritance is also available via mixins and you can write your own implementations of interfaces which are very similar to what an interface implementation would do.
I disagree with “If you reject interfaces, then you should reject CFCs for the same reasons”. I don’t think it’s an arbitrary line at all. There is nothing about OOP that /requires/ an OO language to have interfaces, yet an OO language does require many other things all of which CFC’s already support. As long as you meet some of the basic reqirements of OOP such as classes, objects, inheritance, polymorphism, encpasulation, abstraction, etc., you have an OO language. Not implementing interfaces does not mean you should reject CFC’s.
The whole point being that an implementing an interface within a dynamic language does not solve the fundamental problem which interfaces are designed to solve (see my first paragraph in this response). While an interface tag would provide an implementation of an abstraction, the only way to ensure a contract is followed is by throwing a runtime exception, which in most cases would have happened anyway if the contract weren’t being followed.
If what you said about the implementation of CFC’s is true, then why are there not implementations of interfaces in any other dynamically typed OO language? (Though I assume there’s one out there somewhere that probably does have interfaces, but none that I’m aware of).
Hi Brandon,
I thought it better to respond via a blog entry, rather than a lengthy comment here on your blog:
http://blog.newatlanta.com/ind.....7E58B8EE29
I hope to follow-up with a response to the issue you raise regarding overriding and function signatures, but it’ll probably be next weekend before I have the time.
This is a good discussion and I’m glad you started it, since it’s forced me to think more deeply about my position on this topic and how to present it to a wider audience. (I’d also like to be very clear that my arguments against your position are technical and not personal, and I hope you haven’t taken offense where none is intended.)
Regards.
I think Interfaces are very handy for Software Architects who manages large application with consists of multiple developers.
He can create the Core application framework (controller CFCs and models CFCS – DAO, Gateways) by creating Interface CFCs with complete documentation and pass them to developers.
Developers can later write the logic on their CFC which implements the Interface CFCs written by Architect.
That way Interfaces enforce the developers not to deviate from the coding rules and modeling style proposed by Software Architect.
Continuing the Discussion