Java (1.8+) has an #FunctionalInterface annotation which (basically) suggests that you can pass a method reference in place of an Interface implementation to another method call. The useful one I was playing with today is:
DateTimeFormatter.parse(String, TemporalQuery<T>)
It's nice as it lets you tell the formatter what kind of result to hand back to you. The javadoc even gives you a nice example:
The query is typically a method reference to a from(TemporalAccessor) method. For example:
LocalDateTime dt = parser.parse(str, LocalDateTime::from);
Once I got my head around what the #FunctionalInterface is and means, I started to wonder how a consumer of an API is to figure out what they can actually use in its place. The example above tells you what you can use, and if you trace through the java.time package, you can find other method references you can use. However, any contributors to the API need to read through the entire javadoc to make sure they don't break any implicit contracts mentioned in other places (of course they should, especially for the JDK, but that's not the purpose of javadoc!)
So.. If a contributor to this API were to change the signature of LocalDateTime::from, then there's no compile time checking to say that this method no longer conforms to the FuncitonalInterface of 'TemporalQuery'. This would obviously break any consumers of the API and they could change their code to use an explicit lambda instead. I do understand that it does not need to, but if an annotation, similar to the optional '#Override' annotation were available, then it would provide some compile time checks as well as the possibility of introspecting/reflecting to discover available method references.
e.g.
#ConformsTo(TemporalQuery.class)
public static LocalDateTime from(TemporalAccessor temporal)
It would also then be possible to find, through introspection, any other method references that can be used for a FunctionalInterface.
So, to be clear, I understand that this is not necessary, but do think it seems to be an oversight not to include it as an optional Annotation. Is there any particular reason this could/should not exist?
The problems that arise from changing the signature or return type of a method, e.g. LocalDateTime::from isn't limited to functional interfaces. Even before Java 8 changing those things risked breaking existing code that relied on those things. That's why designing an API is always a challenge because changes to existing code can mean a lot of work.
Additionally, assuming the functional interface and the matching methods are part of different libraries, would you really want that they are closely coupled, i.e. both need to change when one changes? What if they are maintained by different organizations (let's say different open source projects or companies) - how should they coordinate?
As an example take Comparator.comparing(Function<? super T, ? extends U> keyExtractor). That basically accepts a reference to any method that takes no parameter and returns something comparable. There are so many libraries that already provide those methods, would you want them all to have to add #ConformsTo?
That said, a #ConformsTo would at best be incomplete and might even be misleading/outdated.
Edit:
Let's tackle both annotations from the view of the compiler.
#FunctionalInterface tells the compiler that it should complain when you define more than one abstract method or use it on something else other than an interface.
That means that the requirements/contract definition ("this interface is a functional interface") and the implementation (the interface itself) are contained in the same file and thus have to be changed together anyways.
#ConformsTo could tell the compiler to check the requirements of the functional interface (or even interfaces) and see if that method satisfies them.
So far so good, but the problem arises when the interface changes: it would couple the method and the interface which could be part of different and otherwise totally unrelated libraries. And even if they were part of the same library you could run into problems when the method itself wouldn't be recompiled - the compiler might miss that incompatibility and thus defy the purpose of that annotation (if it were only meant for humans then a simple comment would be sufficient as well).
Related
If we have an interface which is being implemented by large number of classes in our application, and we need to add a method to the interface, What is the recommended way to do it?
Would the approach differ if we are using older version of java (let's say 1.5) vs if we are using newer version of java (let's say 1.8).
This won't be a popular answer, but it seems right to me that the operation you envisage is a difficult one.
Interfaces define a service contract between different sub-systems. Changing that contract should be more difficult that changing an implementation. Java 8 introduced "default" methods on interfaces, which converts the interface from being a strict contract, to a kind of abstract base class. I guess it might take some of the sting out of changing interfaces, but I think it's right that developers should feel that sting.
In fact, in an ideal world, all interfaces would be agreed in advance, and there should never be a need to change one. I guess that's impractical, but I see no need to make it easy.
The short answer, I think, is that if you change an interface, you should reflect on what changes are needed in all the implemented classes, grit your teeth, and get on and make them.
you should always follow the principle of "Open for extension Close for modification"
if u add a new method the repercussions will be in all the Classes implementing it , U have to implement the method to all (be it java 5 or 8 until its a default method), so better
Create a new interface and the needful classes should extend it
we need to add a method to the interface
Well then there's no way around it. Without any context for what you're adding and why, I'll take your word for it that you do need to. Make sure that's actually the case.
Java 5: add the method. Fix all the classes implementing it.
You can consider adding a default to a new abstract base class which implements the interface, and make all implementations extend that. Then if you're in the same situation in the future you'll have an easier time.
Java 8: add a default method
In golang, interfaces are extremely important for decoupling and composing code, and thus, an advanced go program might easily define 1000s of interfaces .
How do we evolve these interfaces over time, to ensure that they remain minimal?
Are there commonly used go tools which check for unused functions ?
Are there best practices for annotating go functions with something similar to java's #Override, which ensures that a declared function is properly implementing a expected contract?
Typically in the java language, it is easy to keep code tightly bound to an interface specification because the advanced tooling allows us to find and remove functions which aren't referenced at all (usually this is highlighted automatically for you in any common IDE).
Are there commonly used go tools which check for unused functions ?
Sort of, but it is really hard to be sure for exported interfaces. oracle can be used to find references to types or methods, but only if you have all of the code that references you availible on your gopath.
can you ensure a type implements a contract?
If you attempt to use a type as an interface, the compiler will complain if it does not have all of the methods. I generally do this by exporting interfaces but not implementations, and making a constructor:
type MyInterface interface{
Foo()
}
type impl struct{}
func (i *impl) Foo(){}
func NewImpl() MyInterface{
return &impl{}
}
This will not compile if impl does not implement all of the required functions.
In go, it is not needed to declare that you implement an interface. This allows you to implement an interface without even referencing the package it is defined in. This is pretty much exactly the opposite of "tightly binding to an interface specification", but it does allow for some interesting usage patterns.
What your asking for isn't really a part of Go. There are no best practices for annotating that a function satisfies an interface. I would personally say the only clear best practice is to document which interfaces your types implement so that people can know. If you want to test explicitly (at compile time) if a type implements an interface you can do so using assignment, check out my answer here on the topic; How to check if an object has a particular method?
If you're just looking to take inventory of your code base to do some clean up I would recommend using that assignment method for all your types to generate compile time errors regarding what they don't implement, scale down the declarations until it compiles. In doing so you should become aware of the disparity between what might be implemented and what actually is.
Go is also lacking in IDE options. As a result some of those friendly features like "find all references" aren't there. You can use text searching tricks to get around this, like searching func TheName to get only the declaration and .TheName( to get all invocations. I'm sure you'll get used to it pretty quickly if you continue to use this tooling.
I just making an effort to understand the power of the interfaces and how to use them to the best advantage.
So far, I understood that interfaces:
enable us to have another layer of abstraction, separate the what (defined by the interface) and the how (any valid implementation).
Given just one single implementation I would just build a house (in one particular way) and say here, its done instead of coming round with a building plan (the interface) and ask you, other developers to build it as i expect.
So far, so good.
What still puzzles me is why to favor interface types over class types when it comes to method parameters and return values. Why is that so? What are the benefits (drawbacks of the class approach)?
What interests me the most is how this actually translates into code.
Say we have a sort of pseudo mathInterface
public interface pseudoMathInterface {
double getValue();
double getSquareRoot();
List<Double> getFirstHundredPrimes();
}
//...
public class mathImp implements pseudoMathInterface { }
//.. actual implementation
So in the case of getPrimes() method I would bound it to List, meaning any concrete implementation of the List interface rather than a concerete implementation such as ArrayList!?
And in terms of the method parameter would I once again broaden my opportunities whilst ensuring that i can do with the type whatever i would like to do given it is part of the interface's contract which the type finally implements.!?
Say you are the creator of a Maven dependency, a JAR with a well-known, well-specified API.
If your method requests an ArrayList<Thing>, treating it is a collection of Things, but all I have got is a HashSet<Thing>, your method will twist my arm into copying everything into an ArrayList for no benefit;
if your method declares to return an ArrayList<Thing>, which (semantically) contains just a collection of Things and the index of an element within it carries no meaning, then you are forever binding yourself to returning an actual ArrayList, even though e.g. the future course of the project makes it obvious that a custom collection implementation, specifically tailored to the optimization of the typical use case of this method, is desperately needed to improve a key performance bottleneck.
You are forced to make an API breaking change, again for no benefit to your client, but just to fix an internal issue. In the meantime you've got people writing code which assumes an ArrayList, such as iterating through it by index (there is an extremely slight performance gain to do so, but there are early optimizers out there to whom that's plenty).
I propose you judiciously generalize from the above two statements into general principles which capture the "why" of your question.
An important reason to prefer interfaces for formal argument types is that it does not bind you to a particular class hierarchy. Java supports only single inheritance of implementation (class inheritance), but it supports unlimited inheritance of interface (implements).
Return types are a different question. A good rule of thumb is to prefer the most general possible argument types, and the most specific possible return types. The "most general possible" is pretty easy, and it clearly lines up with preferring interface types for formal arguments. The "most specific possible" return types is trickier, however, because it depends on just what you mean by "possible".
One reason for using interface types as your methods' declared return types is to allow you to return instances of non-public classes. Another is to preserve the flexibility to change what specific type you return without breaking dependent code. Yet another is to allow different implementations to return different types. That's just off the top of my head.
So in the case of getPrimes() method I would bound it to List, meaning any concrete implementation of the List interface rather than a concerete implementation such as ArrayList!?
Yes, this allows the method to later then change what List type it returns without breaking client code that uses the method.
Besides having the ability to change what object is really passed to/returned from a method without breaking code, sometimes it may be better to use an interface type as a parameter/return type to lower the visibility of fields and methods available. This would reduce overall complexity of the code that then uses that interface type object.
I generally oppose extension since it creates a very strong connection between classes, which is easy to accidentally break.
However, I finally thought I'd found a reasonable case for it - I want to optionally use a compressed version of a file type in an existing system. The compressed version would be almost as quick as the uncompressed, and would have exactly the same methods available (i.e. read and write) - the only difference would be in the representation on disk. Therefore, I had the compressed version extend the uncompressed version so that either kind of file could be used, just by optionally insantiating the other type.
public class CompressedSpecialFile extends SpecialFile(){ ... }
if (useCompression){
SpecialFile = new CompressedSpecialFile();
} else {
SpecialFile = new SpecialFile();
}
However, at a later point in the program, we use reflection:
Object[] values = new Object[]{SpecialFile sf, Integer param1, String param2, ...}
Class myclass = Class.forName(algorithmName);
Class[] classes = // created by calling .getClass on each object in values
constructor = myclass.getConstructor(classes);
Algorithm = (Algorithm) constructor.newInstance(values)
Which all worked fine, but now the myclass.getConstructor class throws a NoSuchMethodException since the run-time type of the SpecialFile is CompressedSpecialFile.
However, I thought that was how extension is supposed to work - since CompressedSpecialFile extends SpecialFile, any parameter accepting a SpecialFile should accept a CompressedSpecialFile. Is this an error in Java's reflection, or a failure of my understanding?
Hmm, the response to this bug report seems to indicate that this is intentional.
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4301875
We cannot make this change for compatibility reaons. Furthermore, we
would expect that getConstructor should behave analogously to getDeclaredMethod,
which also requires an exact match, thus it does not make sense to change one
without changing the other. It would be possible to add an additional suite of
methods that differed only in the way in which the argument types were matched,
however.
There are certainly cases where we might want to apply at runtime during
reflection the same overload-resolution algorithm used statically by the
compiler, i.e., in a debugger. It is not difficult to implement this
functionality with the existing API, however, so the case for adding this
functionality to core reflection is weak.
That bug report was closed as a duplicate of the following one, which provides a bit more implementation detail:
http://bugs.sun.com/bugdatabase/view_bug.do;jsessionid=1b08c721077da9fffffffff1e9a6465911b4e?bug_id=4287725
Work Around
Users of getMethod must be precise identifying the Class passed to the argument.
Evaluation
The essence of this request is that the user would like for Class.getMethod
to apply the same overloading rules as the compiler does. I think this is
a reasonable request, as I see a need for this arising frequently in certain
kinds of reflective programs, such as debuggers and scripting interpreters,
and it would be helpful to have a standard implementation so that everybody
gets it right. For compatibility, however, the behavior of the existing
Class.getMethod should be left alone, and a new method defined. There is
a case for leaving this functionality out on the basis of footprint, as it
can be implemented using existing APIs, albeit somewhat inefficiently.
See also 4401287.
Consensus appears to be that we should provide overload resolution in
reflection. Exactly when such functionality is provided would depend largely
on interest and potential uses.
For compatibility reasons, the Class.get(Declared)+{Method,Constructor}
implementation should not change; new method should be introduced. The
specification for these methods does need to be modified to define "match". See
bug 4651775.
You can keep digging into those referenced bugs and the actual links I provided (where there's discussion as well as possible workarounds) but I think that gets at the reasoning (though why a new method reflecting java's oop in reflection as well has not yet been implemented, I don't know).
In terms of workarounds, I suppose that for the one-level-deep version of inheritance, you can just call getSuperclass() on each class whose name is that of the extending class, but that's extremely inelegant and tied to you using it only on your classes implementing in the prescribed manner. Very kludgy. I'll try and look for another option though.
I'm fairly new to programming against interfaces and am trying to get it right as a major tool for developing test driven.
Currently we have a lot of Manager classes that all implement a CRUD interface. However some Managers don't yet do updates and some don't do delete, some may never do so.
Not implemented exception?
Is it okay, to just
throw new NotImplementedException()
until the method gets implemented or even for all time if it never does?
(obviously with a source code comment telling the programmer "this method is not supposed to be used, as e.g. Types like 'male' 'female' do never get deleted)?
Split?
Or should I split my CRUD interface into Creatable, Readable(Searchable), Updatable and Deletable? Wouldn't that clutter my class definition?
PersonManager implements Creatable<Person>, Updateable<Person>, Deletable<Person>, Searchable<Person>
Split and combine?
Or should I combine some interfaces like all 4 into CRUD and maybe some other combinations like Read + Update?
Maybe that would also create a load of interfaces where one has to click through a big inheritence path to find out which interface implements all the desired atomic interfaces for the current situation (I need read and create, so which one just implements the two? and this can get a lot more complex quickly)
IMO, for the middle stage - it is OK to use NotImplementedException, until you finish implementing it.
However, as a permanentsolution - I believe it is a bad practice [in most cases].
Instead, I'd create an interface that contains behavior common to all implementing classes, and use subinterfaces to cluster them up for more specific behavior.
The idea is similar to java standard SortedSet, which extends a Set - we wouldn't want to regard Set as SortedSets and give a variable of this type a value of HashSet, instead we use a sub-interface, SortedSet for this purpose.
Generally you would like to throw UnsupportedOperationException which is a runtime exception, clearly mentioning that the requested operation is not supported.
Having loads of interfaces will lead to too many files and also if someone tries to look at them they will get confused. Java docs don't help much either in such cases.
Splitting interface makes sense if there are too many operations for one interface, and not all operations are logically binded together.
For database operation rarely its the case as you will have some basic operation which will be true for most of the scenario.
NotImplementedException doesn't mean that class doesn't support this action. It means it's not implemented, but it will be in the future.
From logical point of view all interface methods must be implemented, and must work well. But if you leave it, and write an application just for yourself, then you will remember about this limitation. In other hand I would be angry that some developer implemented interface and left it unimplemented. So I don't think you can leave interface method not implemented just for future development.
My suggestion is rather to modify interfaces, then use exceptions inside implemented methods.
In frameworks that support covariance and contravariance, it can be very useful to split up interfaces and then define some composite interfaces. For frameworks that do not offer such support, (and even sometimes on frameworks which do) it is sometimes more helpful to have an interface include methods which individual implementations may or may not support (implementations should throw an exception when unsupported actions are attempted); if one is going to do that, one should include methods or properties by which outside code can ask what actions are supported without needing to use any code that will throw an exception.
Even when using interfaces that where support for actions is optional, however, it may sometimes be helpful to define additional interfaces which guarantee that certain actions will be available. Having interfaces which inherit other interfaces without adding new members can be a good way to do this. If done properly, the only extra work this will require on behalf of implementations is to make sure they declare themselves as the most specific type applicable. The situation for clients is a little more complex: if clients' needs can be adequately expressed in the type system, clients can avoid the need for run-time type-checking by demanding specific types. On the other hand, routines that pass instances between clients may be complicated by some client's demands for more specific type than the instance-passing code itself would otherwise require.