Discussions

News: Eamonn McManus: Java API Design Guidelines

  1. Eamonn McManus: Java API Design Guidelines (60 messages)

    Eamonn McManus, technical lead of the JMX team at Sun, has written "Java API Design Guidelines" for an article at Artima.com, summarizing what he's learned from various sources about designing APIs, spurred on by a talk from Elliotte Rusty Harold (author of XOM, an XML library for Java.)

    The main points, discussed in detail in the article but with selected quotes here, are:
    • Design to evolve
      The best approach is to say that once something is in the API it will stay there and it will continue to work. Tweaking the API incompatibly between revisions will result in user reactions ranging from annoyance to murderous rage. The problem is particularly severe if your API ends up being used by different modules that are part of the same application. If Module 1 uses Commons Banana 1.0 and Module 2 uses Commons Banana 2.0 then life will be a whole lot easier if 2.0 is completely compatible with 1.0. Otherwise your users risk wasting huge amounts of time tweaking classpaths in a futile endeavour to make things work. They might end up having to play mind-destroying games with class-loaders, which is a clear signal that you have failed.
    • [Follow a set of] API Design goals, such as "It must be absolutely correct," "It must be easy to use," "It must be easy to learn," "It must be fast enough," and "It must be small enough," expressed in roughly the order of importance.
    • Be minimalist
      Because of the compatibility requirement, it's much easier to put things in than to take them out. So don't add anything to the API that you're not sure you need.

      ...

      he right approach is to base the API on example code. Think of problems a user might want to solve with the API. Add just enough classes and methods to solve those problems. Code the solutions. Remove anything from the API that your examples don't need. This allows you to check that the API is useful. As a happy side-effect, it gives you some basic tests. And you can (and should) share the examples with your users.
    • Interfaces are overvalued
      There's a certain style of API design that's very popular in the Java world, where everything is expressed in terms of Java interfaces (as opposed to classes). Interfaces have their place, but it is basically never a good idea for an entire API to be expressed in terms of them. A type should only be an interface if you have a good reason for it to be.
      This is followed by a set of circumstances in which an interface is entirely justified.
    • Be careful with packages
      The Java language has fairly limited ways of controlling the visibility of classes and methods. In particular, if a class or method is visible outside its package, then it is visible to all code in all packages. This means that if you define your API in several packages, you have to be careful to avoid being forced to make things public just so that code in other packages in the API can access them.

      The simplest solution to avoid this is to put your whole API in one package. For an API with fewer than about 30 public classes this is usually the best approach.
    • Other random tips, including some well-chosen tips from Effective Java

    What do you think of Eamonn's points? What would you add to the list?

    Threaded Messages (60)

  2. What do you think of Eamonn's points?

    I actually think the points are rather useless in practice - "easy to learn AND easy to use AND fast AND small" are so subjective and elusive goals and the article provides no real advice on how to achieve them

    also the discussion on interfaces vs. abstract classes is a bit too biased. The one from NetBeans is much more objective (http://openide.netbeans.org/tutorial/api-design.html#design.interfacesandclasses)

    Actually the whole "How To Design a (module) API" guide is much better...
  3. Problems?[ Go to top ]

    Doesn't this rather expose whats missing badly in Java? Versioning and a JAR/library scope for classes and methods.
    Versioning should ofcourse be linked with the classloader much like classes are defined by the classloader which loaded the class and its fully quali. name.

    Well - maybe its just me...
  4. Problems?[ Go to top ]

    Doesn't this rather expose whats missing badly in Java? Versioning and a JAR/library scope for classes and methods.Versioning should ofcourse be linked with the classloader much like classes are defined by the classloader which loaded the class and its fully quali. name.Well - maybe its just me...

    It does expose a weakness in Java, *but* the best approach in *any* language is to design for absolute upward compatibility of the API. This has two benefits: (1) source and object code is upward compatible and requires no special tricks and (2) those using your API aren't forced to learn a whole new way to get the results they used to.

    Look at Java itself. If APIs just disappeared, started working differently, etc, versioning and scoping would only solve part of the ensuing problems. The huge problem would be that of incompatibility with existing programmer knowledge.

    As I see it library versioning and scoping are partially a crutch for poor library/API design and/or testing. Inadequate attention was given to compatibility, unit/regression testing, or both.
  5. Problems?[ Go to top ]

    It does expose a weakness in Java, *but* the best approach in *any* language is to design for absolute upward compatibility of the API. This has two benefits: (1) source and object code is upward compatible and requires no special tricks and (2) those using your API aren't forced to learn a whole new way to get the results they used to.Look at Java itself. If APIs just disappeared, started working differently, etc, versioning and scoping would only solve part of the ensuing problems. The huge problem would be that of incompatibility with existing programmer knowledge.As I see it library versioning and scoping are partially a crutch for poor library/API design and/or testing. Inadequate attention was given to compatibility, unit/regression testing, or both.

    Well - I totally agree WHEN were are talking about API as in interfaces/concrete classes, but when you create a library with external dependencies (other libraries) you impose a decision on your users. For an example: Hibernate uses many commons-*.jar libs. This means if I want to use Hibernate in my project/product I have to use the same version of the commons-*.jar libs even though I might want an older or newer version which might break Hibernate (and yes I have seen this in the real world). So if Hibernate was able to say "load commons-logging.jar in version 2.2" (of my head) and I was able to say "load commons-logging in version 3.1". Having the libraries to be self-contained (or with similar version stategy) by using the lib scope would also be of big help... IMHO.. Anyways - Its not a problem I come across often.
  6. Problems?[ Go to top ]

    This means if I want to use Hibernate in my project/product I have to use the same version of the commons-*.jar libs even though I might want an older or newer version which might break Hibernate (and yes I have seen this in the real world). So if Hibernate was able to say "load commons-logging.jar in version 2.2" (of my head) and I was able to say "load commons-logging in version 3.1". Having the libraries to be self-contained (or with similar version stategy) by using the lib scope would also be of big help...

    actually, any OSGi microkernel such as Eclipse (Equinox), Knopflerfish or Oscar should make that possible.

    Of course, developing an OSGi based application is an extra overhead for you
  7. Problems?[ Go to top ]

    Doesn't this rather expose whats missing badly in Java? Versioning and a JAR/library scope for classes and methods.
    +1
  8. Never right the first time[ Go to top ]

    I remember Dave Thomas (the other one, from OTI) saying that you could not have a good reusable API until it had been reused 3 time. I don't know how you can get it right the first time. Agile methodologies express the same sentiment.
  9. Interfaces are overvalued
  10. There's a certain style of API design that's very popular in the Java world, where everything is expressed in terms of Java interfaces (as opposed to classes). Interfaces have their place, but it is basically never a good idea for an entire API to be expressed in terms of them. A type should only be an interface if you have a good reason for it to be.

    If a "type" is like String, Date, etc., then I would agree.

    However, I would argue that many of the problems with the Java API designs were precisely because classes were used instead of interfaces.

    One of the benefits of designing APIs using interfaces is that it forces you to expose your coupling points, and prevents just the types of hacks that prevent people from bending your designs to their needs.

    Peace,

    Cameron Purdy
    Tangosol Coherence: The Java Data Grid
  11. If a "type" is like String, Date, etc., then I would agree.However, I would argue that many of the problems with the Java API designs were precisely because classes were used instead of interfaces.One of the benefits of designing APIs using interfaces is that it forces you to expose your coupling points, and prevents just the types of hacks that prevent people from bending your designs to their needs.

    +1
  12. Interfaces are overvalued
  13. There's a certain style of API design that's very popular in the Java world, where everything is expressed in terms of Java interfaces (as opposed to classes). Interfaces have their place, but it is basically never a good idea for an entire API to be expressed in terms of them. A type should only be an interface if you have a good reason for it to be.
    If a "type" is like String, Date, etc., then I would agree.However, I would argue that many of the problems with the Java API designs were precisely because classes were used instead of interfaces.One of the benefits of designing APIs using interfaces is that it forces you to expose your coupling points, and prevents just the types of hacks that prevent people from bending your designs to their needs.Peace,Cameron PurdyTangosol Coherence: The Java Data Grid

    +1

    Seems like another API maker who have never eaten his own crap.
  14. If a "type" is like String, Date, etc., then I would agree.However, I would argue that many of the problems with the Java API designs were precisely because classes were used instead of interfaces.One of the benefits of designing APIs using interfaces is that it forces you to expose your coupling points, and prevents just the types of hacks that prevent people from bending your designs to their needs.Peace,Cameron Purdy

    Yes but providing an API for every class is not necessarily good either. Doing so can force the API to include implementation details as comments or in other documentation. Once you've let that detail out, it's difficult to change as you've made it part of the contract.

    The point is that if we were to provide an API that included nothing but interfaces, we haven't really provided anything. Interfaces do do anything. They only tell us how to interact with code that does do something. If someone wants to replace root pieces of the framework with their own 'from scratch' implementations, they can do so without implementing an interface. In other words, if the type is not an argument or a member of anything in the API, or requires a very specific relationship between it's methods, defining an interface for it is pointless.

    Encouraging people to define interfaces for their types isn't gong to acomplish much if the types are defined such that there is only one valid implementation. Designing an interface is much more than taking all the public methods of a class and making an interface. I see that a lot and it's often a waste of time and makes a mess of the source. Usually these interfaces start with 'I'.
  15. If a "type" is like String, Date, etc., then I would agree.However, I would argue that many of the problems with the Java API designs were precisely because classes were used instead of interfaces.One of the benefits of designing APIs using interfaces is that it forces you to expose your coupling points, and prevents just the types of hacks that prevent people from bending your designs to their needs.Peace,Cameron Purdy
    Yes but providing an API for every class is not necessarily good either. Doing so can force the API to include implementation details as comments or in other documentation. Once you've let that detail out, it's difficult to change as you've made it part of the contract.The point is that if we were to provide an API that included nothing but interfaces, we haven't really provided anything. Interfaces do do anything. They only tell us how to interact with code that does do something. If someone wants to replace root pieces of the framework with their own 'from scratch' implementations, they can do so without implementing an interface. In other words, if the type is not an argument or a member of anything in the API, or requires a very specific relationship between it's methods, defining an interface for it is pointless.Encouraging people to define interfaces for their types isn't gong to acomplish much if the types are defined such that there is only one valid implementation. Designing an interface is much more than taking all the public methods of a class and making an interface. I see that a lot and it's often a waste of time and makes a mess of the source. Usually these interfaces start with 'I'.

    You can provide both. For example, you can provide an abstract implementation so your API can be used out of the box, but still use and interface so people can modify stuff.
  16. You can provide both. For example, you can provide an abstract implementation so your API can be used out of the box, but still use and interface so people can modify stuff.

    Yes but that doesn't really address my point. Why provide an interface if there is no way for a user of the API to implement it properly? Why provide an iterface for a type that is not a method argument, a return type or (unlikely) a non-final public member? If Mindlessly creating interfaces doesn't improve an API. This is something that some developers clearly don't understand.

    I do take a different slant on this than the article. I say don't provide an interface if there is a good reason not to where the article says to not provide one unless there is a good reason to do so. I would err on the side of providing interfaces for the reasons Cameron pointed out.
  17. Check out dom4j (www.dom4j.org). Its a good example of using interfaces and factories to implement an API. It provides one or more concrete classes that implement each of the interfaces. By extending the factory you can substitute your own implementations (sometimes extending the concrete classes or their abstract parents) and tailor it to fit your needs. It works very well, its easy to learn and easy to customize. I switched to if from jdom (www.jdom.org) which uses concrete classes a few years ago. Dom4j split from jdom sometime ago because of differences among its implementors as to using factories and interfaces versus concrete classes.
  18. Check out dom4j (www.dom4j.org). Its a good example of using interfaces and factories to implement an API. It provides one or more concrete classes that implement each of the interfaces. By extending the factory you can substitute your own implementations (sometimes extending the concrete classes or their abstract parents) and tailor it to fit your needs. It works very well, its easy to learn and easy to customize. I switched to if from jdom (www.jdom.org) which uses concrete classes a few years ago. Dom4j split from jdom sometime ago because of differences among its implementors as to using factories and interfaces versus concrete classes.

    The Dom4J API defines many types that do not have have corresponding interfaces.
  19. Check out dom4j (www.dom4j.org). Its a good example of using interfaces and factories to implement an API. It provides one or more concrete classes that implement each of the interfaces. By extending the factory you can substitute your own implementations (sometimes extending the concrete classes or their abstract parents) and tailor it to fit your needs. It works very well, its easy to learn and easy to customize. I switched to if from jdom (www.jdom.org) which uses concrete classes a few years ago. Dom4j split from jdom sometime ago because of differences among its implementors as to using factories and interfaces versus concrete classes.
    The Dom4J API defines many types that do not have have corresponding interfaces.

    It is open source so you get source and javadoc for many classes. All of the important API classes with a few necesary exceptions are interfaces, i.e. ELEMENT, ATTRIBUTE, etc. are Interfaces. The java collections it uses are Interfaces. Simpler types similar to what Cameron referred to are classes, but we all agreed that it was appropriately so. The point is that the Interfaces (and Factories) are the mainstay of this API. If you work only with the Factory singleton to create the objects you need, you will be dealing almost exclusively with interfaces.
  20. Check out dom4j (www.dom4j.org). Its a good example of using interfaces and factories to implement an API. It provides one or more concrete classes that implement each of the interfaces. By extending the factory you can substitute your own implementations (sometimes extending the concrete classes or their abstract parents) and tailor it to fit your needs. It works very well, its easy to learn and easy to customize. I switched to if from jdom (www.jdom.org) which uses concrete classes a few years ago. Dom4j split from jdom sometime ago because of differences among its implementors as to using factories and interfaces versus concrete classes.
    The Dom4J API defines many types that do not have have corresponding interfaces.
    It is open source so you get source and javadoc for many classes. All of the important API classes with a few necesary exceptions are interfaces, i.e. ELEMENT, ATTRIBUTE, etc. are Interfaces. The java collections it uses are Interfaces. Simpler types similar to what Cameron referred to are classes, but we all agreed that it was appropriately so. The point is that the Interfaces (and Factories) are the mainstay of this API. If you work only with the Factory singleton to create the objects you need, you will be dealing almost exclusively with interfaces.

    And how is this in conflict with what I have written or were you just posting the information as a semi-random comment?
  21. Check out dom4j (www.dom4j.org). Its a good example of using interfaces and factories to implement an API. It provides one or more concrete classes that implement each of the interfaces. By extending the factory you can substitute your own implementations (sometimes extending the concrete classes or their abstract parents) and tailor it to fit your needs. It works very well, its easy to learn and easy to customize. I switched to if from jdom (www.jdom.org) which uses concrete classes a few years ago. Dom4j split from jdom sometime ago because of differences among its implementors as to using factories and interfaces versus concrete classes.
    The Dom4J API defines many types that do not have have corresponding interfaces.
    It is open source so you get source and javadoc for many classes. All of the important API classes with a few necesary exceptions are interfaces, i.e. ELEMENT, ATTRIBUTE, etc. are Interfaces. The java collections it uses are Interfaces. Simpler types similar to what Cameron referred to are classes, but we all agreed that it was appropriately so. The point is that the Interfaces (and Factories) are the mainstay of this API. If you work only with the Factory singleton to create the objects you need, you will be dealing almost exclusively with interfaces.
    And how is this in conflict with what I have written or were you just posting the information as a semi-random comment?

    Your comment about dom4j seemed to confuse the many concrete classes used to implement the framework with those aspects of the framework that constitute an API. I was pointing out that to use dom4j you, for the most part, only work directly with the factory and the interfaces. Your earlier comment seemed to imply that Cameron or someone was suggesting that only interfaces would be delivered as an API. I was pointing out that the API part - the public spec that you rely on could reasonably be interfaces and that this allowed implementors to supply one or more implementations for those interfaces without changing the API.

    The problem with using abstract or concrete classes to define your API is that its users are often forced into using inheritance in order to use it. That is not always a good thing.
  22. Your comment about dom4j seemed to confuse the many concrete classes used to implement the framework with those aspects of the framework that constitute an API.

    In my mind, the API is all the public classes and interfaces provided for use in the framework. Perhaps you have a different understanding of what an API is.
    I was pointing out that to use dom4j you, for the most part, only work directly with the factory and the interfaces. Your earlier comment seemed to imply that Cameron or someone was suggesting that only interfaces would be delivered as an API.

    That was not my intention. My point was defending the idea that it's not always good to provide an interface. It's not always helpful and it's sometimes harmful. It's definitely not a simple covnersion from class to interface.
    I was pointing out that the API part - the public spec that you rely on could reasonably be interfaces and that this allowed implementors to supply one or more implementations for those interfaces without changing the API.

    Only if the interfaces are well designed. The reality is that there are going to be parts of an API that cannot be sensibly described as interfaces. For example, there is no sensible way to define a Abstract Factory with interfaces only.
    The problem with using abstract or concrete classes to define your API is that its users are often forced into using inheritance in order to use it. That is not always a good thing.

    This is the first level of understanding. The next is to realize that just provining interfaces won't make the API extensible in a useful way. The design must be architected for extension (not Java extends) from the ground up. Interfaces are an important tool in this but are not, on their own, a solution.
  23. In my mind, the API is all the public classes and interfaces provided for use in the framework. Perhaps you have a different understanding of what an API is.

    I think we are in general agreement except in this one area which may be because dom4j is not a clean example of an API because the entire framework is open. The API may provide imlementation, but it should not expose it. JAXP and JMS are better examples of pure APIs. We can see the boundaries between them and their reference implementations and they have contracts to complete them. Nevertheless I think most of the posts, yours and mine included, seem to take the middle ground that interfaces can be good and so can abstract and concrete classes, it all depends on the the design, what you are trying to accomplish, what they (classes and interfaces) are representing, etc.

    Back to APIs though, I would argue that classes, as well as interfaces, are not sufficient in terms of an API, in fact they can be misleading. You really need to publish contracts stating pre and post conditions, error handling, qos, etc. Specify which methods are part of the API and versus those for internal use. (Given the scoping limitations of languages like Java.) Contracts can and should be written for both interfaces and classes. They are what makes an API complete, not code. Method signatures are insufficient and exposing implementation code is dangerous because developers may assume that how you implement a function or service is part of the contract.
    This is the first level of understanding.

    Don't you think that this statement is a bit patronizing? This is my 27th year in the field, 19 in OO, developed in a dozen or more languages, yada yada. I think I'm beyond the first level by now.
  24. This is the first level of understanding.
    Don't you think that this statement is a bit patronizing? This is my 27th year in the field, 19 in OO, developed in a dozen or more languages, yada yada. I think I'm beyond the first level by now.

    No offense meant. When you wrote "The problem with using abstract or concrete classes to define your API is that its users are often forced into using inheritance in order to use it. That is not always a good thing." I felt it something we could assume we both already knew. I could either be a patronizing statement on your part or it could mean that you thought this was something really important to point out. It made me think you weren't getting my point. I was merely pointing out that this was assumed to be understood in my argument.
  25. In my mind, the API is all the public classes and interfaces provided for use in the framework. Perhaps you have a different understanding of what an API is.

    I think we are in general agreement except in this one area which may be because dom4j is not a clean example of an API because the entire framework is open. The API may provide imlementation, but it should not expose it.

    Exactly. dom4j includes both an API and an API implementation.

    Peace,

    Cameron Purdy
    Tangosol Coherence: The Java Data Grid
  26. In my mind, the API is all the public classes and interfaces provided for use in the framework. Perhaps you have a different understanding of what an API is.
    I think we are in general agreement except in this one area which may be because dom4j is not a clean example of an API because the entire framework is open. The API may provide imlementation, but it should not expose it.
    Exactly. dom4j includes both an API and an API implementation.Peace,Cameron PurdyTangosol Coherence: The Java Data Grid

    Just so we are clear, org.dom4j.DocumentFactory is part of the API, right?
  27. Just so we are clear, org.dom4j.DocumentFactory is part of the API, right?

    Yes. According to its javadoc, the interfaces and classes in org.dom4j and org.dom4j.io are the "core" API. So, most of the API is delivered as interfaces, but there a a few classes as well. They struck a nice balance which is what we've all been advocating, right?
  28. Just so we are clear, org.dom4j.DocumentFactory is part of the API, right?
    Yes. According to its javadoc, the interfaces and classes in org.dom4j and org.dom4j.io are the "core" API. So, most of the API is delivered as interfaces, but there a a few classes as well. They struck a nice balance which is what we've all been advocating, right?

    Yes. However, I'd like to re-stir the pot. I've been thinking about this a bit.

    I think interfaces are oversold. Don't get me wrong, I like them and I think they should be used when appropriate but I don't think there are that many cases where not having an interface makes it impossible to implement something.

    The only time you really need an interface is if an Object must be of two unrelated types at once. If I'm developing an API and make no such requirement, the only reason this would be true is because of some external requirement.
  29. However, I'd like to re-stir the pot. I've been thinking about this a bit.I think interfaces are oversold. Don't get me wrong, I like them and I think they should be used when appropriate but I don't think there are that many cases where not having an interface makes it impossible to implement something.The only time you really need an interface is if an Object must be of two unrelated types at once. If I'm developing an API and make no such requirement, the only reason this would be true is because of some external requirement.

    I developed in OO for years without interfaces, so I know I can live without them, but I have found that they are really useful in a number of cases including the one you cited. I'm a software architect who creates or cobbles together (steal code, don't write it) various frameworks and thngs. If you are creating a framework and you want to pass objects that have common roles, but you don't know or want to restrict what class is being passed, than an interface is nice. (The alternative was to have to wrap classes or use a lot of inheritance which gets messy.) In fact for my rule of thumb is interfaces are for roles you play and classes are for what you are.

    Dom4j is a good example again. I've written from scratch classes that implement Element but do many more really useful things and don't have much else in common with the implementation classes dom4j supplies and yet I can still take advantage of all dom4j's facilities. (I also have inherited from an implementation class when that makes sense, too.) I've done the same with middle tier frameworks, etc.

    Granted, in some of these cases I've also used abstract classes where and when I want to assert more control or implement class specific features like dependency injection via contructors or XML serializers or other features.

    Anyway, since you also like interfaces, I'm sure you've appreciated all these things as well. So, if by saying that interfaces are oversold you are referring to the many inappropriate uses some zeolots make of them, I agree completely. But you know, it seems to me that there are folks who misuse almost any feature of Java you can name and others who complain about the existance of the feature because of the misuse. Generics (I like them when used with care) come to mind as they have recently been a topic of much discussion. I used them in Ada and have been waiting for them to appear in Java. Now I'd also like package friends and code macros for those very useful reusable snippets.

    Your turn to stir.
  30. Anyway, since you also like interfaces, I'm sure you've appreciated all these things as well. So, if by saying that interfaces are oversold you are referring to the many inappropriate uses some zeolots make of them, I agree completely. But you know, it seems to me that there are folks who misuse almost any feature of Java you can name and others who complain about the existance of the feature because of the misuse. Generics (I like them when used with care) come to mind as they have recently been a topic of much discussion. I used them in Ada and have been waiting for them to appear in Java. Now I'd also like package friends and code macros for those very useful reusable snippets.Your turn to stir.

    I guess my point goes back to the fact that the designer has to weigh the advantages and disadvantages of both. Sometimes the answer is clear cut, other times it is not. Sometimes when it's not clear, the designer chooses a class and people piss and moan about how an interface was not provided so they were unable to do what they wanted. I just wonder if they are not considering other options such as composition.

    Let's take the XOM framework for example. The main representative types (Node, Element, etc.) are not interfaces. What problem does this really cause? When does someone need an Element to also be some other type simultaneously?
  31. When does someone need an Element to also be some other type simultaneously?

    Good question because in fact I have needed to do this or at least I found it to be a very good solution to a few problems. I alluded to it earlier when I said that I've created a class that could play the role of an (org.dom4j.)Element but had little in common with any of their implementation classes. It was one of the reasons why I switched to dom4j from jdom. On several projects I found it useful to create lightweight domain or value objects that could work as XML without the overhead and without loosing their other characteristics (non-String value types, structure). I could use these objects in my application and then treat them as XML nodes within the dom4j framework when I ever I needed to to do things like transforms, xpath searches and message serialization. For me, Element was a role, not a type.
  32. When does someone need an Element to also be some other type simultaneously?
    Good question because in fact I have needed to do this or at least I found it to be a very good solution to a few problems. I alluded to it earlier when I said that I've created a class that could play the role of an (org.dom4j.)Element but had little in common with any of their implementation classes. It was one of the reasons why I switched to dom4j from jdom. On several projects I found it useful to create lightweight domain or value objects that could work as XML without the overhead and without loosing their other characteristics (non-String value types, structure). I could use these objects in my application and then treat them as XML nodes within the dom4j framework when I ever I needed to to do things like transforms, xpath searches and message serialization. For me, Element was a role, not a type.

    OK but was there a reason that you couldn't do this with an inner class on your type? It seems a little strange to work with a class that has all the XML specific methods in non-xml contexts.
  33. When does someone need an Element to also be some other type simultaneously?
    Good question because in fact I have needed to do this or at least I found it to be a very good solution to a few problems. I alluded to it earlier when I said that I've created a class that could play the role of an (org.dom4j.)Element but had little in common with any of their implementation classes. It was one of the reasons why I switched to dom4j from jdom. On several projects I found it useful to create lightweight domain or value objects that could work as XML without the overhead and without loosing their other characteristics (non-String value types, structure). I could use these objects in my application and then treat them as XML nodes within the dom4j framework when I ever I needed to to do things like transforms, xpath searches and message serialization. For me, Element was a role, not a type.
    OK but was there a reason that you couldn't do this with an inner class on your type? It seems a little strange to work with a class that has all the XML specific methods in non-xml contexts.

    There were other ways I could implement it, but none seemed as elegant. Remember, the Element interface basically only required me to produce and accept my values as Strings. The other requirements were simple to implement or delegate to others. More importantly I did not have to inherit from another class and then no-op structures and methods. If anything it did point out to me that Element and some of the other dom4j interfaces have too many convenience methods - methods that are redundant because they either combine what other methods do or perform some additional pre-processing in addition to what another method already does.

    The over use of inheritance is a pet peeve of mine. I'm a composition/delegation type of guy. Its easier to maintain and extend (as software, not classes) as you undoubtedly know.

    I am not big on inner classes either. I do use them, but sparingly. Maybe in part its due to early bugs in different IDEs and compilers, like VisualAge that turned me off them. I also am cautious about maintaining encapsulation and limiting dependencies.

    In any case, because all my value objects implemented Element, I could leverage all that dom4j code transparently and I didn't have to worry about future changes in their Element implementation classes. For me that is the (or one of the) greatest benefits of interfaces. I can implement frameworks that do not force its users to extend my classes, just comply with my required behaviors and I can implement classes that do what I need them to do without surrending the benefits of a framework or API I want to leverage.
  34. There were other ways I could implement it, but none seemed as elegant.

    Without seeing the design, it's hard for me to really understand but in general, I've steered clear from implementing two (non-trivial) interfaces in a single class. A lot of it comes down to the intent of the Object. For example, it's a business Object and not a business Object and a view (XML is a view in my work.) If I want to re-cast the type for another context, I keep that separate from it's 'true' API. I find this procduces much cleaner APIs. Lets say this class you've create now needs to be used as input to a Swing view. Do you now implement TableModel (for example) or if it needs to be in a web container, do you implement another interface? We want to treat it as a map, now we implement Map. It doesn't take many of these additions to create a really complicated and bloated API.
    Remember, the Element interface basically only required me to produce and accept my values as Strings. The other requirements were simple to implement or delegate to others. More importantly I did not have to inherit from another class and then no-op structures and methods.

    My issue with this is not the way it's implemented, its that when this class is used outside the context of XML, these methods are not really meaningful. Would you have normally 'accepted input as a String'? Let's say you bring on a junior developer. Will that developer understand that these methods are only for the dom4j framework? You've also coupled your API to a 3rd party tool, something I've seen cause serious problems in the past.
    The over use of inheritance is a pet peeve of mine. I'm a composition/delegation type of guy. Its easier to maintain and extend (as software, not classes) as you undoubtedly know.

    That's the thing, I see this as an overuse of inheritance. In this case it's inheritance of definition but still problematic.
    I am not big on inner classes either. I do use them, but sparingly.

    You don't have to use them to get the same effect. They are convienient to me because I can create Objects that have access to the internal of my type while keeping them private.
    In any case, because all my value objects implemented Element, I could leverage all that dom4j code transparently and I didn't have to worry about future changes in their Element implementation classes.

    Hmmm. You are susceptible to changes in the interface (unlikely) and changes in the contracts of the interfaces.
    For me that is the (or one of the) greatest benefits of interfaces. I can implement frameworks that do not force its users to extend my classes, just comply with my required behaviors

    I agree completely when the framework can do this effectively. I don't think it should be forced because of ideology.
    and I can implement classes that do what I need them to do without surrending the benefits of a framework or API I want to leverage.

    You lost me there. What would cause you to have to surrender the benefits of the API?
  35. You lost me there. What would cause you to have to surrender the benefits of the API?

    I'm referring to the 3rd party API for which I'm implementing the interface. If an API accepts an interface instead of a class, I am less constrained as to my class design. I can just add the interface implementation. I can either add the code to my class or delegate the work to another class - inner or a field.

    If the API requires a class, I either have to use the class it designates or extend that class. If I use their class and its a bad fit, I am not getting what I need. If I extend their class and its a bad fit I may have to do a lot of no-ops in the extension class. Other I can a way of moving my values between their class and mine, but if their values are private and they don't have public getters and setters for everything, its not possible. If they require a given class and I don't do any of these things, then I cannot leverage their services.

    I'd much rather explain some additional methods implemented to satisfy an interface than explain a poor choice of class extension and the complexity and dependencies it introduces. If I'm going to depend on a 3rd party, depending on their interface is usually much more reliable and less constraining than depending on their implementations.
  36. If I use their class and its a bad fit, I am not getting what I need. If I extend their class and its a bad fit I may have to do a lot of no-ops in the extension class. Other I can a way of moving my values between their class and mine, but if their values are private and they don't have public getters and setters for everything, its not possible. If they require a given class and I don't do any of these things, then I cannot leverage their services. I'd much rather explain some additional methods implemented to satisfy an interface than explain a poor choice of class extension and the complexity and dependencies it introduces. If I'm going to depend on a 3rd party, depending on their interface is usually much more reliable and less constraining than depending on their implementations.

    Any public type that a API provides is a contract as much as an interface is. Just because there is no interface doesn't mean that there is only an implementation. When the class is public and extensible it's just as binding a contract as an interface.

    If an API only provides an Element class, there's nothing stoping you from overriding all the public and protected non-final methods as if you were implementing an interface. It's really not very different from implementing an interface.
  37. If I use their class and its a bad fit, I am not getting what I need. If I extend their class and its a bad fit I may have to do a lot of no-ops in the extension class. Other I can a way of moving my values between their class and mine, but if their values are private and they don't have public getters and setters for everything, its not possible. If they require a given class and I don't do any of these things, then I cannot leverage their services. I'd much rather explain some additional methods implemented to satisfy an interface than explain a poor choice of class extension and the complexity and dependencies it introduces. If I'm going to depend on a 3rd party, depending on their interface is usually much more reliable and less constraining than depending on their implementations.
    Any public type that a API provides is a contract as much as an interface is. Just because there is no interface doesn't mean that there is only an implementation. When the class is public and extensible it's just as binding a contract as an interface.If an API only provides an Element class, there's nothing stoping you from overriding all the public and protected non-final methods as if you were implementing an interface. It's really not very different from implementing an interface.

    It really is different because the class I am extending is likely to have structures as well as methods. If I am not using the structures and end up over-riding all the public methods (as would have been the case), then what is the point of inheritance? No-oping your ancestors is one of the no-no's of OO (Riel, Object-Oriented Design Heuristics, 1996). With an interface its simple and clean. I have nothing to no-op or over-ride and no baggage.

    I once worked at a major corp cleaning up their java. Some "expert" told them to use inheritance instead of interfaces because interfaces use indirection (??!!?).
    They ended up with an inheritance hierarchy over 15 levels deep and unused structures and no-oped methods all over the place. What made it worse was they did not use lazy instantiation of heavyweight structures like HashMaps. The HashMaps and other fields were all private so you couldn't even reuse them with your own methods. It was a mess. Much of the inheritance was so their infrastructure frameworks could process their objects.
  38. It really is different because the class I am extending is likely to have structures as well as methods.

    I should have added that I'd get rid of fields while I was at it ;-)

    Peace,

    Cameron Purdy
    Tangosol Coherence: Clustered Shared Memory for Java
  39. It really is different because the class I am extending is likely to have structures as well as methods. If I am not using the structures and end up over-riding all the public methods (as would have been the case), then what is the point of inheritance?

    From a high-level OO perspective, yes there is no point. Pragmatically, with regards to how the code actually executes, it makes little difference. You will have some extra Object data lying around but that's more of an optimization concern.
    No-oping your ancestors is one of the no-no's of OO (Riel, Object-Oriented Design Heuristics, 1996). With an interface its simple and clean. I have nothing to no-op or over-ride and no baggage.

    I'm not sure I follow. If you don't have a valid implementation for a method, don't you have to provide a no-op implementation in order to satisfy the interface?
    I once worked at a major corp cleaning up their java. Some "expert" told them to use inheritance instead of interfaces because interfaces use indirection (??!!?).They ended up with an inheritance hierarchy over 15 levels deep and unused structures and no-oped methods all over the place. What made it worse was they did not use lazy instantiation of heavyweight structures like HashMaps. The HashMaps and other fields were all private so you couldn't even reuse them with your own methods. It was a mess. Much of the inheritance was so their infrastructure frameworks could process their objects.

    Of course interfaces provide value but so do abstract classes and concrete classes. I'm not saying that interfaces are not good to use, I just don't think it;s good to use them at all costs. Sometimes the advantages of forcing a parent class outwiegh these issues. We've already agreed on this. My point was that not providing an interface isn't as draconian as some people make it out to be. There ways to work out issues without interfaces even if an interface should have been provided.

    There is an interesting feature of Scala that allows self-type definitions. The interesting piece is that it allows you to declare that instances of this class will be of a specific type even if that type has no relationship to the one being defined. The reason why I mention this is... Maybe you can tell me why I thought this was pertinent.
  40. From a high-level OO perspective, yes there is no point. Pragmatically, with regards to how the code actually executes, it makes little difference. You will have some extra Object data lying around but that's more of an optimization concern.

    Au contraire! HashMaps at the default size, for example, are huge even when empty. When I added lazy instantiation to their classes for all their collections, it reduced each user's heap use by 20MB! No kidding! (It was an insurance applications with lots of objects and lots of state.)
    I'm not sure I follow. If you don't have a valid implementation for a method, don't you have to provide a no-op implementation in order to satisfy the interface?

    No-oping an interface is not as harmful because we are not talking about inheritance - just implementation. I would question why an interface method that can harmlessly be no-oped is included in the first place, but its possible.

    On the other hand, the fact that you are no-oping an ancestor means you had no business extending it in the first place. Inheritance, as UML shows, is really generalization going up. That means that the class being generalized from has only the common structures and behaviors. If it does not, its a clue that its not a generalization.
    Of course interfaces provide value but so do abstract classes and concrete classes. I'm not saying that interfaces are not good to use, I just don't think it;s good to use them at all costs.

    I agree of course.
    My point was that not providing an interface isn't as draconian as some people make it out to be. There ways to work out issues without interfaces even if an interface should have been provided.

    I agree with that as well.
    There is an interesting feature of Scala that allows self-type definitions. The interesting piece is that it allows you to declare that instances of this class will be of a specific type even if that type has no relationship to the one being defined. The reason why I mention this is... Maybe you can tell me why I thought this was pertinent.

    Mmmmm!? Did I misunderstand or that the same effect as a marker interface? Please explain how that works.
  41. From a high-level OO perspective, yes there is no point. Pragmatically, with regards to how the code actually executes, it makes little difference. You will have some extra Object data lying around but that's more of an optimization concern.
    Au contraire! HashMaps at the default size, for example, are huge even when empty. When I added lazy instantiation to their classes for all their collections, it reduced each user's heap use by 20MB! No kidding! (It was an insurance applications with lots of objects and lots of state.)

    That's what I meant by 'optimization concern'. I's definitely wasteful but the way the JVM looks up the methods is unaffected.
    No-oping an interface is not as harmful because we are not talking about inheritance - just implementation. I would question why an interface method that can harmlessly be no-oped is included in the first place, but its possible.On the other hand, the fact that you are no-oping an ancestor means you had no business extending it in the first place. Inheritance, as UML shows, is really generalization going up. That means that the class being generalized from has only the common structures and behaviors. If it does not, its a clue that its not a generalization.

    Right, but this is still from a high-level OO perspective. The way the code operates in terms of how the methods are looked-up and executed is not really any different.

    Generally, if you have to rewrite the entire class, it probably should have been an interface in the first place. However, I find that people rarely use interfaces for this purpose. They use them to cast another concrete type as a second type and use composition to bring in a concrete implementation. They are using the existing implementation (perhaps overriding parts of it). So if you let go of having a type that is both Element and MyBusinessObject, it's not usually an issue that an inteface wasn't provided.

    Personally, I like interfaces because they separate the contract from the implementaiton. It's cleaner and makes people think about the difference.
    There is an interesting feature of Scala that allows self-type definitions. The interesting piece is that it allows you to declare that instances of this class will be of a specific type even if that type has no relationship to the one being defined. The reason why I mention this is... Maybe you can tell me why I thought this was pertinent.
    Mmmmm!? Did I misunderstand or that the same effect as a marker interface? Please explain how that works.
    Not quite. It would be like declaring a class Foo and specifiying a self-type that says it's a Bar. In the Foo class, you can use 'this' as if it's a Bar, even though there is nothing about Foo (apart from the self-type) that would imply this would be a Bar. So at runtime (I guess) it fails if this is not a Bar.

    I think I remembered why I thought of this. It sort of solves the interface vs. force an implementation detail problem. I can declare an abstract type and say its has a self-type of a concrete type that contains my implementation detail. Then implementors can bring in the concrete type as a mixin. Of course this is from someone who hasn't tried using Scala at all yet (but I plan to.)
  42. I'd like to re-stir the pot. I've been thinking about this a bit.I think interfaces are oversold. Don't get me wrong, I like them and I think they should be used when appropriate but I don't think there are that many cases where not having an interface makes it impossible to implement something.

    Actually, I'd like to rev the language and get rid of interfaces altogether ;-). Think about it: If you have mix-ins and duck typing, then regular classes could be interfaces (substitutability by quacking).

    Peace,

    Cameron Purdy
    Tangosol Coherence: The Java Data Grid
  43. I'd like to re-stir the pot. I've been thinking about this a bit.I think interfaces are oversold. Don't get me wrong, I like them and I think they should be used when appropriate but I don't think there are that many cases where not having an interface makes it impossible to implement something.
    Actually, I'd like to rev the language and get rid of interfaces altogether ;-). Think about it: If you have mix-ins and duck typing, then regular classes could be interfaces (substitutability by quacking).Peace,Cameron PurdyTangosol Coherence: The Java Data Grid

    I'm not sure I undersand what you would like. It would be nice to be able to use anything that fufills an interface's requirements as an instance of that interface without directly implementing the interface but I'm not sure I would like to have duck typing in the sense where you don't have to declare a type at all. I work with lots of developers (many temporary) on code that was written by other temporary developers that only exist in legend (AFAIK) and as dumb as some of the interfaces are, they do bring stability and consistency to the code. There's so much spagetthi code that no one knows exactly how it all works. If there were no types, we'd surely be constantly digging through trying to find errors that appear from strange places when we change the requirments for a method. I also like to be able to select a type and ask for all implementors. I'm not sure how that would work in a 'type-less' language.
  44. I'd like to re-stir the pot. I've been thinking about this a bit.I think interfaces are oversold. Don't get me wrong, I like them and I think they should be used when appropriate but I don't think there are that many cases where not having an interface makes it impossible to implement something.
    Actually, I'd like to rev the language and get rid of interfaces altogether ;-). Think about it: If you have mix-ins and duck typing, then regular classes could be interfaces (substitutability by quacking).Peace,Cameron PurdyTangosol Coherence: The Java Data Grid
    I'm not sure I undersand what you would like. It would be nice to be able to use anything that fufills an interface's requirements as an instance of that interface without directly implementing the interface but I'm not sure I would like to have duck typing in the sense where you don't have to declare a type at all. I work with lots of developers (many temporary) on code that was written by other temporary developers that only exist in legend (AFAIK) and as dumb as some of the interfaces are, they do bring stability and consistency to the code. There's so much spagetthi code that no one knows exactly how it all works. If there were no types, we'd surely be constantly digging through trying to find errors that appear from strange places when we change the requirments for a method. I also like to be able to select a type and ask for all implementors. I'm not sure how that would work in a 'type-less' language.

    O.K. guys, I'm confused here. To implement an Interface you have to implement all of its method signatures, if any. This seems necessary because the reason I declare an argument by Interface may be because I am going to call any one of those methods and things should work. If my programming language won't let me call a method unless I know about it and its signature, what good will it do me if you implement a different method or signature that does the same thing? It seems to defeat the point doesn't it?

    Maybe I don't know what you mean by "duck typing" and "mix-ins". Please explain.

    Also, agreeing with James, I hate having to guess at what code does and what it expects. Being precise and specific it seems to me is a good thing. I don't like programmers who do things seat of the pants. If they do, I want them to at least go back and insure there is structure, order, precision, and specificity to what they do. Its better for everyone if the mistakes are easier to identify.
  45. I don't know what you mean by "duck typing" and "mix-ins".

    Mix-ins are objects that are basically a dynamic composition of othe Objects. Let's say I need an Object to be an Map and an Element (whatever), in Java, I would have to declare a type that implements Map and Element and then implement the methods usually with composition. With a mixin you basically take two types or Object and glue them together with some syntactical sugar paste.

    The term Duck typing apparently comes from the pharse 'if it looks like a duck and quacks like a duck...' In duck-typing if your type has all the methods in the Map interface (for example) you can pass to a method that requires a map, even if you don't explicitly implement map. With mix-ins, this allows some fancy code tricks. some duck-typing systems don't even require the method to state a type, rather the requirements are implicit in the code from what is used on the Object. This last system is what I really don't care for. Two methods could require the same 'type' but you'd only know that by looking at the code and even then it could just be incidental and change tomorrow.
  46. scala mixin[ Go to top ]

    Check this out: http://scala.epfl.ch/intro/mixin.html

    Scala's kind of cool because it's fully OO and functional and is built to work with Java classes natively and runs on a JVM (and .NET if you work for the Empire.)
  47. scala mixin[ Go to top ]

    Check this out: http://scala.epfl.ch/intro/mixin.htmlScala's kind of cool because it's fully OO and functional and is built to work with Java classes natively and runs on a JVM (and .NET if you work for the Empire.)

    Cool! What I've wanted for awhile is the ability in Java to declare an interface and then assign its methods to those of one or more classes - in the interface itself or some glue declaration. (Doesn't VB6 have this? That would be ironic.) After all, why should an interface have to be entirely implemented by one class?

    How long has scala been around? You say it runs in a JVM? Does that include the 1.5 JVM?
  48. scala mixin[ Go to top ]

    Check this out: http://scala.epfl.ch/intro/mixin.htmlScala's kind of cool because it's fully OO and functional and is built to work with Java classes natively and runs on a JVM (and .NET if you work for the Empire.)
    Cool! What I've wanted for awhile is the ability in Java to declare an interface and then assign its methods to those of one or more classes - in the interface itself or some glue declaration. (Doesn't VB6 have this? That would be ironic.) After all, why should an interface have to be entirely implemented by one class? How long has scala been around? You say it runs in a JVM? Does that include the 1.5 JVM?

    I can't say for sure. I assume it would, I just don't know that it takes advantage of the new features i.e. I doubt it would provide generics without a change to the language. I've seen references to the lack of generics in Java (which scala supports and more fully) in the scala documentation. I'm guessing that means they haven't implemented support for Java generics.
  49. scala mixin[ Go to top ]

    How long has scala been around?

    I just discovered it recently. I couldn't find a history on the homepage.
  50. Mix-ins are objects that are basically a dynamic composition of othe Objects.
    Not quite: mix-ins are a static composition of objects, not a dynamic one.

    The Strategy pattern will give you dynamic implementation mix-ins but changing the type of an object at runtime is not possible in Java.

    Otherwise, I share your concerns with duck typing and I expressed them here.

    --
    Cedric
  51. Mix-ins are objects that are basically a dynamic composition of othe Objects.
    Not quite: mix-ins are a static composition of objects, not a dynamic one.

    I thought mixins were supported dynamically in some languages like Ruby. But whatever, I'm definitely no expert in that area.
  52. I thought mixins were supported dynamically in some languages like Ruby. But whatever, I'm definitely no expert in that area.
    No, you declare mix-ins statically (at compile-time). They are similar to multiple inheritance of implementation, as provided in C++.

    --
    Cedric
  53. The term Duck typing apparently comes from the pharse 'if it looks like a duck and quacks like a duck...'

    Are you sure he doesn't mean 'duck taping'? ;)
  54. I'm not sure I undersand what you would like. It would be nice to be able to use anything that fufills an interface's requirements as an instance of that interface without directly implementing the interface ..

    Exactly! Or, more importantly, I'd like to be able to substitute any class for any other class if it provides the necessary methods.

    Take as one example the InputStream and OutputStream classes in Java. They should have been interfaces, but the early Java developers (2 or 3 guys at Sun) made classes and abstract classes instead, so that they could save re-typing 2 or 3 lines of code, like read(byte[]) calling read(byte[], int, int) for example. Any time we want to save some re-usable code and apply it in multiple places, we should be thinking "mix ins" instead of "abstract classes". Any time we need to substitute one class in place of another, why should we be worried about inheritance hierarchies?

    Peace,

    Cameron Purdy
    Tangosol Coherence: Clustered Shared Memory for Java
  55. I'm not sure I undersand what you would like. It would be nice to be able to use anything that fufills an interface's requirements as an instance of that interface without directly implementing the interface ..
    Exactly! Or, more importantly, I'd like to be able to substitute any class for any other class if it provides the necessary methods.Take as one example the InputStream and OutputStream classes in Java. They should have been interfaces, but the early Java developers (2 or 3 guys at Sun) made classes and abstract classes instead, so that they could save re-typing 2 or 3 lines of code, like read(byte[]) calling read(byte[], int, int) for example. Any time we want to save some re-usable code and apply it in multiple places, we should be thinking "mix ins" instead of "abstract classes". Any time we need to substitute one class in place of another, why should we be worried about inheritance hierarchies?Peace,Cameron PurdyTangosol Coherence: Clustered Shared Memory for Java

    In regards to scala, do you think it's on track? I think it goes a little too far. It infers types for me? Smacks to much of VB for my taste. I like static typing in that we should have to declare the requirements of a Object formally but I don't like how the compiler is so bureaucratic about how we fufill that contract.
  56. Actually, I'd like to rev the language and get rid of interfaces altogether ;-). Think about it: If you have mix-ins and duck typing, then regular classes could be interfaces (substitutability by quacking).Peace,Cameron PurdyTangosol Coherence: The Java Data Grid

    I've been flirting with Scala lately. I don't pretend to really have a great grasp on it yet but it's type system is very interesting. Are you thinking on those lines, or something else?
  57. The problem with using abstract or concrete classes to define your API is that its users are often forced into using inheritance in order to use it. That is not always a good thing.

    Like other people pointed out in this thread, it might or might not be a good thing. The disadvantage clearly is less flexibility, but the advantage is that you can both hide more implementation details and make stronger guarantees on the contract. It's just all a big game of weighing pros against cons instead of the 'make everything an interface' mantra that buzzed around last year.
  58. You can provide both. For example, you can provide an abstract implementation so your API can be used out of the box, but still use and interface so people can modify stuff.
    Yes but that doesn't really address my point. Why provide an interface if there is no way for a user of the API to implement it properly? Why provide an iterface for a type that is not a method argument, a return type or (unlikely) a non-final public member? If Mindlessly creating interfaces doesn't improve an API. This is something that some developers clearly don't understand.I do take a different slant on this than the article. I say don't provide an interface if there is a good reason not to where the article says to not provide one unless there is a good reason to do so. I would err on the side of providing interfaces for the reasons Cameron pointed out.

    Think of simple Beans and a simple CRUD API for persistance. My experience is that it's easier to plug in a transparent cache if your CRUD API and the Beans are both defined by Interfaces. Why for the beans? Your cache has to control changes on all objects that it has cached. Say a client gets a bean from the cache, he changes on of it's value but does not persist it immediately. without further control all other clients of the same cache would see the changed value though it's not valid because of lacking persistance. If the cache wraps all objects it hands out to the user, it may do a dispose-from-cache-on-client-change style functionality. A changed bean will be disposed and replaced by the valid persistant copy red from the persistance backend.
    Furthermore with the help of dynamic proxies it's possible to write ONE class for that sort of cache-control functionality and reuse it for each and every Bean that has an interface.
    There would be a second approach to the cache-bean thingy, it's bytecode instrumentation like hibernate does, wich works for classes to But it has it's advantages and disadvantages. The most outstanding disadvantage is that dynamic bytecode instrumentation is sort of NONE debugable at all. So you live or die with the implementation you use and it's bugs. Therefore I prefer my way... I did it my way ;-)
    Coming back to dynamic proxies. I Think this is an outstanding feature which overs plenty of possibility. You're able to plug in transparently: access control, caching, logging, intercetors, event generating and so forth. It's like aspect programming for the poor man...
    I know that some of you mnight say that there might be severe performance problems. But belief me: I have never got performance problems with dynamic proxies to this day. They work for me and that's why I like interfaces.
    Cheers,
    Peter
  59. Think of simple Beans and a simple CRUD API for persistance. My experience is that it's easier to plug in a transparent cache if your CRUD API and the Beans are both defined by Interfaces. Why for the beans? Your cache has to control changes on all objects that it has cached. Say a client gets a bean from the cache, he changes on of it's value but does not persist it immediately. without further control all other clients of the same cache would see the changed value though it's not valid because of lacking persistance. If the cache wraps all objects it hands out to the user, it may do a dispose-from-cache-on-client-change style functionality. A changed bean will be disposed and replaced by the valid persistant copy red from the persistance backend.

    I don't see why creating an interface for the bean is required to do this
    Furthermore with the help of dynamic proxies it's possible to write ONE class for that sort of cache-control functionality and reuse it for each and every Bean that has an interface.

    Can you explain how this is not possible using a class?
    There would be a second approach to the cache-bean thingy, it's bytecode instrumentation like hibernate does, wich works for classes to But it has it's advantages and disadvantages. The most outstanding disadvantage is that dynamic bytecode instrumentation is sort of NONE debugable at all. So you live or die with the implementation you use and it's bugs. Therefore I prefer my way... I did it my way ;-)Coming back to dynamic proxies. I Think this is an outstanding feature which overs plenty of possibility. You're able to plug in transparently: access control, caching, logging, intercetors, event generating and so forth. It's like aspect programming for the poor man...I know that some of you mnight say that there might be severe performance problems. But belief me: I have never got performance problems with dynamic proxies to this day. They work for me and that's why I like interfaces.Cheers,Peter

    None of this seems pertinent to the discussion. Perhaps you can elaborate.
  60. [..] providing an API for every class is not necessarily good either. Doing so can force the API to include implementation details as comments or in other documentation. Once you've let that detail out, it's difficult to change as you've made it part of the contract.

    This is very true. I don't suggest designing an API with all interfaces, (not in Java, that is). As I mentioned, some "types" deserve to be classes, and I think you said it very well here:
    Encouraging people to define interfaces for their types isn't gong to acomplish much if the types are defined such that there is only one valid implementation.

    However, I do not agree with this:
    The point is that if we were to provide an API that included nothing but interfaces, we haven't really provided anything. Interfaces [don't] do anything.

    Interfaces _do_ do something: they provide the "black" in "black box" more effectively than the other choices available when working in Java.
    If someone wants to replace root pieces of the framework with their own 'from scratch' implementations, they can do so without implementing an interface.

    Unfortunately, this is rarely true. Most API "designers" are (as you suggest) simply reverse-engineering an implementation into an API design. Doing so makes a mockery of the concept behind an "API".
    Designing an interface is much more than taking all the public methods of a class and making an interface.

    Exactly. If there is a class already (before the API exists), then you've allowed the proverbial cart to get in front of the equally proverbial horse.

    I would also add (for completeness) that most things do not need an API.

    Peace,

    Cameron Purdy
    Tangosol Coherence: The Java Data Grid
  61. However, I do not agree with this:
    The point is that if we were to provide an API that included nothing but interfaces, we haven't really provided anything. Interfaces [don't] do anything.
    Interfaces _do_ do something: they provide the "black" in "black box" more effectively than the other choices available when working in Java.

    I may not have been clear here. What I mean is that if all an API provides is interfaces and contains no implementations, it's at most a prescription for a solution. It's not actually a solution. Now take a leap with me. If all types in the API, are defined as intefaces but implementations are provided, there will be at least some interfaces that don't make sense. Maybe I'm overstating my point here.
    If someone wants to replace root pieces of the framework with their own 'from scratch' implementations, they can do so without implementing an interface.
    Unfortunately, this is rarely true. Most API "designers" are (as you suggest) simply reverse-engineering an implementation into an API design. Doing so makes a mockery of the concept behind an "API".

    Let's say I have a abstract factory ParserFactory. Nothing in the API uses this ParserFactory. It's provided solely for the user of the API to retreive Parser instances. If the user wants to re-engineer their own parser factory, they can do so whether I provide an interface for ParserFactory or not. Their code is only thing that will use thier factory and they can just use it in their code without any help from me. I know it's not that simple, but I have seen so many anbstract factories that were never reused because their scope is so narrow.

    I think we are in agreement. I suppose my problem is that here are too many rules of thumb and not enough good discussion about why things should be done a certain way or not. I felt the guidelines here were fairly decent in that regard, even if I don't agree with every point.
  62. Interfaces are overvalued
  63. There's a certain style of API design that's very popular in the Java world, where everything is expressed in terms of Java interfaces (as opposed to classes). Interfaces have their place, but it is basically never a good idea for an entire API to be expressed in terms of them. A type should only be an interface if you have a good reason for it to be.
    If a "type" is like String, Date, etc., then I would agree.However, I would argue that many of the problems with the Java API designs were precisely because classes were used instead of interfaces.One of the benefits of designing APIs using interfaces is that it forces you to expose your coupling points, and prevents just the types of hacks that prevent people from bending your designs to their needs.Peace,Cameron PurdyTangosol Coherence: The Java Data
    Grid

    +1

    Common sense that is lacking so often...
  64. Packages are a good instrument to organise your code and expose your API in with an intuitive structure.

    However, I agree with the comment in the article that package are not flexible in Java. If you need to access your public classes, it forces you to put them in the same package or use some naming conventions to separate your system classes.

    Using naming conventions are OK when you have formal release process and document it with JavaDoc. However, when you work in a large team and work with the source code, it requires some getting used to. I used a naming convention for a framework, where the non-public classes were put in the "system" packages, similar to "internal" in the article.

    I do not agree with the idea of putting all the classes in the same package. It quickly grows into a bloated, unintuitive package like java.util where we have date and collection classes.

    In an ideal world, we should have more control. Possibly

    1) With something like declaring a friend packages.
    2) Another easy alternative would be assuming parent, child package relationship and allowing child package to access to parent's default level classes.