tag:blogger.com,1999:blog-17547394.post6323554618318168270..comments2023-03-24T13:39:26.449-05:00Comments on Boris Bokowski: Accidental ComplexityBoris Bokowskihttp://www.blogger.com/profile/06344587055927544695noreply@blogger.comBlogger7125tag:blogger.com,1999:blog-17547394.post-14092195209228188632008-10-16T22:50:00.000-05:002008-10-16T22:50:00.000-05:00I've made a more elaborate post to your blog post ...I've made a more elaborate post to your blog post at <A HREF="http://ketan.padegaonkar.name/2008/10/17/complexities-of-apis.html" REL="nofollow">my blog</A>KetanPadegaonkarhttps://www.blogger.com/profile/00708547712729097047noreply@blogger.comtag:blogger.com,1999:blog-17547394.post-21534390741375489452008-09-30T15:31:00.000-05:002008-09-30T15:31:00.000-05:00Great advice guys. The other thing that helped us...Great advice guys. The other thing that helped us for Mylyn 3.0 is adopting the new @noimplement tag for the case where we know we'll need to add methods to the interface.<BR/><BR/>I just noticed a great summary listing of API best practice from Bloch: <A HREF="http://www.infoq.com/articles/API-Design-Joshua-Bloch" REL="nofollow"> http://www.infoq.com/articles/API-Design-Joshua-Bloch</A><BR/><BR/>Fyi, the additions to his second edition of "Effective Java" are a great read if you haven't flipped through them yet.<BR/><BR/>--<BR/>Mik Kersten<BR/>President & CTO, <A HREF="http://tasktop.com/blog" REL="nofollow">http://tasktop.com/blog</A><BR/>Project Lead, <A HREF="http://eclipse.org/mylyn" REL="nofollow">http://eclipse.org/mylyn</A>Mik Kerstenhttps://www.blogger.com/profile/00097030325844385383noreply@blogger.comtag:blogger.com,1999:blog-17547394.post-83015081273360427812008-09-29T09:16:00.000-05:002008-09-29T09:16:00.000-05:00@Mik and Boris' reply: the lesson I learned is, "...@Mik and Boris' reply: the lesson I learned is, "Never hand out an interface for someone else to implement". Period. Mik, your solution of abstract classes to subclass is I now believe the right approach and I think we've started doing that now in the platform (but too late).<BR/><BR/>As for the many nouns, its an excellent point. Gads it makes my head hurt. In general, complexity breeds more complexity. But that's a simplistic answer. I'd like us to take a particular example and kind of turn it into a case, maybe we'd then understand the more general pattern that gets us into trouble. I'm not sure if its driven from a need to make things extensible in ways which weren't required. We should look at places where we left the door open for extension/modification and see if anyone actually did so. Another thing I've noticed is that we sometimes try to be too helpful in giving folks reusable bits, which then drives up the complexity for us, for little real gain.Kevin McGuirehttps://www.blogger.com/profile/01803890168169785360noreply@blogger.comtag:blogger.com,1999:blog-17547394.post-85228618461797701422008-09-26T10:32:00.000-05:002008-09-26T10:32:00.000-05:00Mik - yes, in many cases, abstract base classes ar...Mik - yes, in many cases, abstract base classes are a much better choice than interfaces. Way back when we worked on Eclipse 1.0, we tried to use interfaces for everything and ended up overusing them.<BR/><BR/>Another technique that helps is separating client API from provider API. If nobody else is supposed to implement your interface, you can extend it without breaking binary compatibility. For provider API (sometimes called SPI), you can then use separate mechanisms that work better, for example abstract base classes, or a mixin-style with interfaces that won't change over time, but where clients can optionally implement additional interfaces when they step up to newer versions.<BR/><BR/>Finally, a lot of cases where we ended up with I*n names are listener interfaces where we felt the need to add more detail to the generated events. The best practice for this is to have only a single method in the listener interface, handleEvent, and to pass in an event object that can grow additional fields over time.Boris Bokowskihttps://www.blogger.com/profile/06344587055927544695noreply@blogger.comtag:blogger.com,1999:blog-17547394.post-239027314035657382008-09-26T10:21:00.000-05:002008-09-26T10:21:00.000-05:00Sven - yes, I agree. I just wasn't sure if I shoul...Sven - yes, I agree. I just wasn't sure if I should mention dependency injection in this post. Unfortunately, the word 'dependencu injection' sounds so, well, complicated and unnatural, while the concept really is simple and elegant. But I am getting ahead of myself... I should write a dedicated post about dependency injection.Boris Bokowskihttps://www.blogger.com/profile/06344587055927544695noreply@blogger.comtag:blogger.com,1999:blog-17547394.post-14310862784088983432008-09-26T10:16:00.000-05:002008-09-26T10:16:00.000-05:00Great post Boris. Regarding the I*n interfaces, I...Great post Boris. <BR/><BR/>Regarding the I*n interfaces, I remember feeling a combination of anger and disappointment when I first learned about this idiom way back ;) I had been coding around what I thought were shortcomings in the interfaces, and had no idea I had more at my disposal. Then the disappointment set in when I realized that this was actually the only reasonable way to evolve interfaces while persevering binary compatibility. In addition to complexity, I think that one of its biggest costs is discoverability for newcomers to the API. At least that was the case for me.<BR/><BR/>To address this, in select places where it was appropriate, on Mylyn we have used abstract classes with no implementation instead of interfaces (similar to the JDK's MouseAdapter pattern). This has allowed us to add methods without breaking clients. In some places we have only extracted an interface from those abstract classes when we had a release or two of feedback on extensions of the abstract class. <BR/><BR/>Earlier this month I spoke with Juergen Hoeller, the Spring Framework Guru, and asked how they deal with this problem and presented our approach. He's taken the approach of indtrsf giving the I*n interfaces a descriptive name and trying to separate their roles. Sometimes that can turn out more awkward, and you can into an awkward noun game with IMumbleFooExtension style naming. <BR/><BR/>My current thinking is that the I*n approach will never go away, and that we should admit defeat and use the consistency of this approach to help developers with additional tool support. For example, when implementing an interface or doing content assist in a class there could be an "Also see IMumble2" pointer that would make the developer aware of the additional interfaces. Alternatively, we could try to convince newcommers to hit Ctrl+T on ever single new interface they across :)<BR/><BR/>Regarding preferences, I think they're evil: <A HREF="http://wiki.eclipse.org/Mylyn/UI_Design#Idioms" REL="nofollow">http://wiki.eclipse.org/Mylyn/UI_Design#Idioms</A><BR/><BR/>--<BR/>Mik Kersten<BR/>President & CTO, <A HREF="http://tasktop.com/blog" REL="nofollow">http://tasktop.com/blog</A><BR/>Project Lead, <A HREF="http://eclipse.org/mylyn" REL="nofollow">http://eclipse.org/mylyn</A>Mik Kerstenhttps://www.blogger.com/profile/00097030325844385383noreply@blogger.comtag:blogger.com,1999:blog-17547394.post-86071986372117667872008-09-25T23:50:00.000-05:002008-09-25T23:50:00.000-05:00I'd like to see all the singletons being replaced ...I'd like to see all the singletons being replaced by a nice and simple dependency injection framework.<BR/><BR/>In addition we should really strive for allowing bundles being started and stopped at runtime (aka dynamic modules). Dependency Injection will help here. <BR/><BR/>I think there's no doubt that we need to further enhance our APIs but need to be backward compatible at the same time. Maybe a more progressive API-lifecycle (i.e. more use of deprecated and more removement of things which have been deprecated for some time) would make the code base clearer.Anonymoushttps://www.blogger.com/profile/11751196715155150517noreply@blogger.com