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.
Related
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).
when programming in Java I practically always, just out of habit, write something like this:
public List<String> foo() {
return new ArrayList<String>();
}
Most of the time without even thinking about it. Now, the question is: should I always specify the interface as the return type? Or is it advisable to use the actual implementation of the interface, and if so, under what circumstances?
It is obvious that using the interface has a lot of advantages (that's why it's there). In most cases it doesn't really matter what concrete implementation is used by a library function. But maybe there are cases where it does matter. For instance, if I know that I will primarily access the data in the list randomly, a LinkedList would be bad. But if my library function only returns the interface, I simply don't know. To be on the safe side I might even need to copy the list explicitly over to an ArrayList:
List bar = foo();
List myList = bar instanceof LinkedList ? new ArrayList(bar) : bar;
but that just seems horrible and my coworkers would probably lynch me in the cafeteria. And rightfully so.
What do you guys think? What are your guidelines, when do you tend towards the abstract solution, and when do you reveal details of your implementation for potential performance gains?
Return the appropriate interface to hide implementation details. Your clients should only care about what your object offers, not how you implemented it. If you start with a private ArrayList, and decide later on that something else (e.g., LinkedLisk, skip list, etc.) is more appropriate you can change the implementation without affecting clients if you return the interface. The moment you return a concrete type the opportunity is lost.
For instance, if I know that I will
primarily access the data in the list
randomly, a LinkedList would be bad.
But if my library function only
returns the interface, I simply don't
know. To be on the safe side I might
even need to copy the list explicitly
over to an ArrayList.
As everybody else has mentioned, you just mustn't care about how the library has implemented the functionality, to reduce coupling and increasing maintainability of the library.
If you, as a library client, can demonstrate that the implementation is performing badly for your use case, you can then contact the person in charge and discuss about the best path to follow (a new method for this case or just changing the implementation).
That said, your example reeks of premature optimization.
If the method is or can be critical, it might mention the implementation details in the documentation.
Without being able to justify it with reams of CS quotes (I'm self taught), I've always gone by the mantra of "Accept the least derived, return the most derived," when designing classes and it has stood me well over the years.
I guess that means in terms of interface versus concrete return is that if you are trying to reduce dependencies and/or decouple, returning the interface is generally more useful. However, if the concrete class implements more than that interface, it is usually more useful to the callers of your method to get the concrete class back (i.e. the "most derived") rather than aribtrarily restrict them to a subset of that returned object's functionality - unless you actually need to restrict them. Then again, you could also just increase the coverage of the interface. Needless restrictions like this I compare to thoughtless sealing of classes; you never know. Just to talk a bit about the former part of that mantra (for other readers), accepting the least derived also gives maximum flexibility for callers of your method.
-Oisin
Sorry to disagree, but I think the basic rule is as follows:
For input arguments use the most generic.
For output values, the most specific.
So, in this case you want to declare the implementation as:
public ArrayList<String> foo() {
return new ArrayList<String>();
}
Rationale:
The input case is already known and explained by everyone: use the interface, period. However, the output case can look counter-intuitive.
You want to return the implementation because you want the client to have the most information about what is receiving. In this case, more knowledge is more power.
Example 1: the client wants to get the 5th element:
return Collection: must iterate until 5th element vs return List:
return List: list.get(4)
Example 2: the client wants to remove the 5th element:
return List: must create a new list without the specified element (list.remove() is optional).
return ArrayList: arrayList.remove(4)
So it's a big truth that using interfaces is great because it promotes reusability, reduces coupling, improves maintainability and makes people happy ... but only when used as input.
So, again, the rule can be stated as:
Be flexible for what you offer.
Be informative with what you deliver.
So, next time, please return the implementation.
In OO programming, we want to encapsulate as much as possible the data. Hide as much as possible the actual implementation, abstracting the types as high as possible.
In this context, I would answer only return what is meaningful. Does it makes sense at all for the return value to be the concrete class? Aka in your example, ask yourself: will anyone use a LinkedList-specific method on the return value of foo?
If no, just use the higher-level Interface. It's much more flexible, and allows you to change the backend
If yes, ask yourself: can't I refactor my code to return the higher-level interface? :)
The more abstract is your code, the less changes your are required to do when changing a backend. It's as simple as that.
If, on the other hand, you end up casting the return values to the concrete class, well that's a strong sign that you should probably return instead the concrete class. Your users/teammates should not have to know about more or less implicit contracts: if you need to use the concrete methods, just return the concrete class, for clarity.
In a nutshell: code abstract, but explicitly :)
In general, for a public facing interface such as APIs, returning the interface (such as List) over the concrete implementation (such as ArrayList) would be better.
The use of a ArrayList or LinkedList is an implementation detail of the library that should be considered for the most common use case of that library. And of course, internally, having private methods handing off LinkedLists wouldn't necessarily be a bad thing, if it provides facilities that would make the processing easier.
There is no reason that a concrete class shouldn't be used in the implementation, unless there is a good reason to believe that some other List class would be used later on. But then again, changing the implementation details shouldn't be as painful as long as the public facing portion is well-designed.
The library itself should be a black box to its consumers, so they don't really have to worry about what's going on internally. That also means that the library should be designed so that it is designed to be used in the way it is intended.
It doesn't matter all that much whether an API method returns an interface or a concrete class; despite what everyone here says, you almost never change the implementiation class once the code is written.
What's far more important: always use minimum-scope interfaces for your method parameters! That way, clients have maximal freedom and can use classes your code doesn't even know about.
When an API method returns ArrayList, I have absolutely no qualms with that, but when it demands an ArrayList (or, all to common, Vector) parameter, I consider hunting down the programmer and hurting him, because it means that I can't use Arrays.asList(), Collections.singletonList() or Collections.EMPTY_LIST.
As a rule, I only pass back internal implementations if I am in some private, inner workings of a library, and even so only sparingly. For everything that is public and likely to be called from the outside of my module I use interfaces, and also the Factory pattern.
Using interfaces in such a way has proven to be a very reliable way to write reusable code.
The main question has been answered already and you should always use the interface. I however would just like to comment on
It is obvious that using the interface has a lot of advantages (that's why it's there). In most cases it doesn't really matter what concrete implementation is used by a library function. But maybe there are cases where it does matter. For instance, if I know that I will primarily access the data in the list randomly, a LinkedList would be bad. But if my library function only returns the interface, I simply don't know. To be on the safe side I might even need to copy the list explicitly over to an ArrayList.
If you are returning a data structure that you know has poor random access performance -- O(n) and typically a LOT of data -- there are other interfaces you should be specifying instead of List, like Iterable so that anyone using the library will be fully aware that only sequential access is available.
Picking the right type to return isn't just about interface versus concrete implementation, it is also about selecting the right interface.
You use interface to abstract away from the actual implementation. The interface is basically just a blueprint for what your implementation can do.
Interfaces are good design because they allow you to change implementation details without having to fear that any of its consumers are directly affected, as long as you implementation still does what your interface says it does.
To work with interfaces you would instantiate them like this:
IParser parser = new Parser();
Now IParser would be your interface, and Parser would be your implementation. Now when you work with the parser object from above, you will work against the interface (IParser), which in turn will work against your implementation (Parser).
That means that you can change the inner workings of Parser as much as you want, it will never affect code that works against your IParser parser interface.
In general use the interface in all cases if you have no need of the functionality of the concrete class. Note that for lists, Java has added a RandomAccess marker class primarily to distinguish a common case where an algorithm may need to know if get(i) is constant time or not.
For uses of code, Michael above is right that being as generic as possible in the method parameters is often even more important. This is especially true when testing such a method.
You'll find (or have found) that as you return interfaces, they permeate through your code. e.g. you return an interface from method A and you have to then pass an interface to method B.
What you're doing is programming by contract, albeit in a limited fashion.
This gives you enormous scope to change implementations under the covers (provided these new objects fulfill the existing contracts/expected behaviours).
Given all of this, you have benefits in terms of choosing your implementation, and how you can substitute behaviours (including testing - using mocking, for example). In case you hadn't guessed, I'm all in favour of this and try to reduce to (or introduce) interfaces wherever possible.
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.
I have some doubts while comparing C++ and Java multiple inheritance.
Even Java uses multiple, multi-level inheritance through interfaces - but why doesnt it use anything like a virtual base class as in C++ ? Is it because the members of a java interface are being ensured one copy in memory (they are public static final), and the methods are only declared and not defined ?
Apart from saving memory, is there any other use of virtual classes in C++ ? Are there any caveats if I forget to use this feature in my multiple inheritance programs ?
This one is a bit philosophical - but why didnt the C++ developers made it a default to make every base class, virtual ? What was the need of providing flexibility ?
Examples will be appreciated. Thanks !!
1) Java interfaces dont have attributes. One reason for virtual base classes in c++ is to prevent duplicate attributes and all the difficulties associated with that.
2) There is at least a slight performance penalty for using virtual base classes in c++. Also, the constructors become so complicated, that it is advised that virtual base classes only have no-argument constructors.
3) Exactly because of the c++ philosphy: One should not require a penalty for something which one may not need.
Sorry - not a Java programmer, so short on details. Still, virtual bases are a refinement of multiple inheritance, which Java designers always defended ommiting on the basis that it's overly complicated and arguably error-prone.
virtual bases aren't just for saving memory - the data is shared by the different objects inheriting from them, so those derived types could use it to coordinate their behaviour in some way. They're not useful all that often, but as an example: object identifiers where you want one id per most-derived object, and not to count all the subobjects. Another example: ensuring that a multiply-derived type can unambiguously map / be converted to a pointer-to-base, keeping it easy to use in functions operating on the base type, or to store in containers of Base*.
As C++ is currently Standardised, a type deriving from two classes can typically expect them to operate independently and as objects of that type tend to do when created on the stack or heap. If everything was virtual, suddenly that independence becomes highly dependent on the types from which they happen to be derived - all sorts of interactions become the default, and derivation itself becomes less useful. So, your question is why not make the default virtual - well, because it's the less intuitive, more dangerous and error-prone of the two modes.
1.Java multiple inheritance in interfaces behaves most like virtual inheritance in C++.
More precisely, to implement java-like inheritance model in c++ you need to use c++ virtual base classes.
However, one of the disadvantages of c++ virtual inheriritance (except of small memory and performance penalty) is the impossibility to static_cast<> from base to derived, so rtti (dynamic_cast) need to be used
(or one may provide "hand made" virtual casting functions for child classes if a list of
such child classes are known in advance)
2.if you forget "virtual" qualifier in inheritance list, it usually lead to compiler error
since any casting frome drived to base class becomes ambigious
3.Philosophical questions usually are quite dificult to answer... c++ is a multiparadigm (and multiphilosophical) language and doesn't impose any philosophical decisions. You may use virtual inheritance whenever possible in you own projects, and (you are rioght) it has a good reason. But such a maxima may be unacceptable for others, so universal c++ tools (standard and other widely used libraries) should be (if possible) free of any particular philosophical conventions.
I'm working on an open source project which basically is translating a large C++ library to Java. The object model of the original creature in C++ can be pretty complicated sometimes. More than necessary, I'd say... which was more or less the motto of Java designers... well... this is another subject.
The point is that I've written an article which shows how you can circumvent type erasure in Java. The article explains well how it can be done and, in the end how your source code can eventually resemble C++ very closely.
http://www.jquantlib.org/index.php/Using_TypeTokens_to_retrieve_generic_parameters
An immediate implication of the study I've done is that it would be possible to implement virtual base classes in your application, I mean: not in Java, not in the language, but in your application, via some tricks, or a lot of tricks to be more precise.
In case you do have interest for such kind of black magic, the lines below may be useful for you somehow. Otherwise certainly not.
Ok. Let's go ahead.
There are several difficulties in Java:
1. Type erasure (solved in the article)
2. javac was not designed to understand what a virtual base class would be;
3. Even using tricks you will not be able to circumvent difficulty #2, because this difficulty appears at compilation time.
If you'd like to use virtual base classes, you can have it with Scala, which basically solved difficulty #2 by exactly creating another compiler, which fully understands some more sophisticated object models, I'd say.
if you'd like to explore my article and try to "circunvent" virtual base classes in pure Java (not Scala), you could do something like I explain below:
Suppose that you have something like this in C++:
template<Base>
public class Extended : Base { ... }
It could be translate to something like this in Java:
public interface Virtual<T> { ... }
public class Extended<B> implements Virtual<B> { ... }
OK. What happens when you instantiate Extended like below?
Extended extended = new Extended<Base>() { /* required anonymous block here */ }
Well.. basically you will be able to get rid of type erasure and will be able to Obtain type information of Base inside your class Extended. See my article for a comprehensive explanation of the black magic.
OK. Once you have type of Base inside Extended, you can instantiate a concrete implementation of Virtual.
Notice that, at compile time, javac can verify types for you, like in the example below:
public interface Virtual<Base> {
public List<Base> getList();
}
public class Extended<Base> implements Virtual<Base> {
#Override
public List<Base> getList() {
// TODO Auto-generated method stub
return null;
}
}
Well... despite all effort to implement it, in the end we are doing badly what an excellent compiler like scalac does much better than us, in particular it is doing its job at compile time.
I hope it helps... if not confused you already!
Is there any way we can inject new methods and properties into classes during run-time.
http://nurkiewicz.blogspot.com/2009/09/injecting-methods-at-runtime-to-java.html states we may do that by using Groovy.
Is it possible by just doing using Java?
Is it possible by just doing using
Java?
The simple answer is an emphatic "You don't want to do that!".
It is technically possible, but not without resorting to extremely complex, expensive and fragile tricks like bytecode modification1. And even then, you have to rely on dynamic loading to access the modified type and (probably) reflection to make use of its new members. In short, you would be creating lots of pain for yourself, for little if any gain.
Java is a statically typed language, and adding / modifying class type signatures can break the static typing contract of a class.
1 - AspectJ and the like allow you to inject additional behaviour into a class, but it is probably not the "runtime" injection that you are after. Certainly, the injected methods won't be available for statically compiled code to call.
So if you were really crazy, you could do something like what they outline here. What you could do is load the .java file, find the correct insertion point, add whatever methods you need to, call the java compiler and reload the class. Good luck debugging that mess though :)
Edit This actually might be of some use...
You can do some quite funky things with AOP, although genuine modification of classes at runtime is a pretty hairy technique that needs a lot of classloading magic and sleight of hand.
What is easier is using AOP techniques to generate a subclass of your target class and to introduce new methods into this instead, what AOP called a "mixin" or "introduction". See here to read how Spring AOP does it, although this may be quite lame compared to what you're actually trying to achieve.
Is it possible by just doing using Java?
Quite so, the "only" thing you have to do is define an instrumentation agent which supplies an appropriate ClassFileTransformer, and you'll have to use reflection to invoke the added methods. Odds are this isn't what you want to do, though, but it's doable and there's a well-defined interface for it. If you want to modify existing methods you may be interested in something like AspectJ.
While it might be possible, it is not useful.
How would you access these new fields and methods?
You could not use these methods and fields directly (as "ordinary" fields and methods), since they wouldn't be compiled in.
If all you want is the possibility to add "properties" and "methods", you can use a Map<String, Object> for the "dynamic properties", and a Map<String, SuitableInterface> for the "dynamic methods", and look them up by name.
If you need an extension language for Java, an embedded dynamic language (such as Javascript, or Groovy) can be added; most of these can access arbitrary java objects and methods.