Right, this is my last thread for today, all I have done is post shite.
I am feeling as if it is time I actually learn to do proper interface design, I have had a good look over LibGDX and how it is basically fully designed with interfaces. I sort of get how it works but at the same time it confuses the hell out of me.
Hit me with your best Interface Design articles, tutorials, books whatever.
I want to learn this sorcery! I shall Extend no more, I must implement!
Hum, interface design ;D
I love interfaces, but most of what I’ve learned is from trial and error.
I would recommend Joshua Bloch’s Effective Java book for general programming practices many of which are related to interfaces.
Online, maybe start with general design principles like:
For example, it’s a very helpful that InputStream and DataInput are interfaces that do not require extending and can be implemented by any class.
However, it’s also very helpful that there are default implementations for these interfaces such as FileInputStream, ObjectInputStream, and ByteArrayInputStream.
It’s important to balance a package, module, or API with both interfaces and default implementations (commonly preceded by the word Abstract in the Java libraries). For example: ListModel has an abstract and default implementation, making it much more useful.
Whereas something like TimerTask is more annoying to use since it must be extended. In my opinion, TimerTask could have been a concrete class with a constructor that took a Runnable object and ran that object instead of forcing every class that ever wanted to use TimerTask to extend it.
public class Thing {
private int id;
private Element matter;
public Thing(int id, Element matter) {
this.id = id;
this.matter = matter;
}
public void thingStuff() {
// ...
}
}
public class ThingBuilder implements Builder<Thing> {
private int thingId;
private Element thingMatter;
public void setId(int id) {
this.thingId = id;
}
public void setElement(Element matter) {
this.thingMatter = matter;
}
@Override
public Thing create() {
return new Thing(thingId, thingMatter);
}
}
public interface Builder<T> {
public T create();
}
public interface XyzService {
// various service methods...
}
public interface XyzProvider {
public XyzService newXyzService();
}
public class Services {
private static final Map<String, XyzProvider> providers = new ConcurrentHashMap<String, XyzProvider>();
public static void registerProvider(String name, XyzProvider p) {
providers.put(name, p);
}
public static XyzService newInstance(String name) {
XyzProvider p = providers.get(name);
if(p == null) { throw new IllegalArgumentException("No provider registered with the name '" + name + "'"); }
return p.newXyzService();
}
}
-Adapted from Effective Design Item 1.
For example, in java.util.concurrent Executor serves the role of XyzService in our example and Executors fulfills the role of Services in our example.
Good interface design is normally about abstracting away details, such as hiding a database connection so that it could easily be replaced with a file or hiding LWJGL’s rendering system so that you can easily modify it for better performance or update it when a new version of LWJGL comes out.
Good interface design is nice when it’s applicable, certainly better than tangled spaghetti code, but notice one thing:
All the examples here (libGDX, java.io, service providers, Executors) are APIs, specifically public APIs.
While having a well thought-out, clearly segmented codebase is attractive, two (at least) things will become apparent: if everything you do becomes an API, you will never get anything done. I can can attest to that, as it’s a bad habit of mine. Also, massively engineered codebases have a certain, different spaghetti-ness to them. I remember a recent comment by princec describing it:
So, while one cannot be expected to know bad code from good code right off the bat, please don’t get sucked into the sometimes nearly religious adoption of a certain ‘style’ or ‘way’ of programming, because it’s usually never good used alone. Develop and use judgement when using these ‘patterns.’ See EnterpriseFizzBuzz for a hilarious example of abuse of what, when used properly and in moderation, are perfectly fine practices in OOP.
Then consider that that actually happens, and you stop laughing.
I’m sure Roquen will pop in with something if he sees this thread, I remember he has something to say about interface design.
Maybe not for a game but I mean that practically the entire library is made with Interfaces, that is what makes me think “that’s cool I want to learn that!”.
Every little thing I learn is a plus, since I am going to study game development getting a grasp of how API’s are designed might be a good thing.
Thanks for the reply, that is a lot to take in lol.
When talking specifically about interfaces, yes I believe it is good practise to use them a lot. The thing is, that this forces people to do composition over inheritance which is nice. Just don’t over do it(like with everything), so pls no [icode]ISomething, SomthingImpl[/icode] all over the code-base.
Of the three major class-based OO structural design choices: design-by-{inheritance, composition, interface}. design-by-interface is the weakest under the assumption you’re also being data driven. JDK 8 significantly improves the situation but it’s still the weakest. IMHO it is still mostly appropriate for type cross cuts, which composition can also cover. JDK-8 gives an extra option for pseudo mixins and can drop some of the boilerplate PITA. The worst case situation for {inheritance, composition} is that the table dereference(s) must occur. The worst case situation for interface is it must perform a dynamic look-up to figure out offsets then perform the dereferences. It does nothing to break-up a monolithic instance data-store and still with JDK-8 additions requires the most boilerplate and artificial introduction of types. On the flip side since we can now define method signatures a la:
@FunctionalInterface
public interface SomeMethodSigDef
{
public WhateverReturn method(WhateverParameters);
}
This is not really an interface, but a call-site definition. That’s interesting.