You can fake mixins in Java. They're great when you want to refactor common functionality from two classes having different superclasses. Just make a new class called FooMixin to hold the common functionality -- the magic of inner classes handles the rest. Here's a real-world example from the OpenJUMP open-source GIS project:
public class LoadDatasetFromFilePlugIn extends AbstractLoadDatasetPlugIn {Note that the LoadSaveDatasetFileMixin has access to the main class (via template methods like #getName, #getLastDirectoryKey), and the main class of course has access to the mixin (via #setSelectedFormat, #getSelectedFormat). Beautiful.
protected void setSelectedFormat(String format) {
loadSaveDatasetFileMixin.setSelectedFormat(format);
}
protected String getSelectedFormat() {
return loadSaveDatasetFileMixin.getSelectedFormat();
}
protected Collection showDialog(WorkbenchContext context) {
final JFileChooser fileChooser = GUIUtil
.createJFileChooserWithExistenceChecking();
fileChooser.setDialogType(JFileChooser.OPEN_DIALOG);
fileChooser.setMultiSelectionEnabled(true);
return loadSaveDatasetFileMixin.showDialog(fileChooser,
LoadFileDataSourceQueryChooser.class, context);
}
private LoadSaveDatasetFileMixin loadSaveDatasetFileMixin = new LoadSaveDatasetFileMixin() {
protected String getName() {
return LoadDatasetFromFilePlugIn.this.getName();
}
protected String getLastDirectoryKey() {
return LoadDatasetFromFilePlugIn.this.getLastDirectoryKey();
}
public boolean isAddingExtensionIfRequested() { return false; }
public File initiallySelectedFile(File currentDirectory) { return null; }
};
}
Check out the classic Effective Java from Joshua Bloch for more about that. Item 16 ...
ReplyDeleteHi Manfred - Hm! Interesting to see the idea of mixins mentioned in print.
ReplyDeleteNice photos.
ReplyDeleteThanks FF!
ReplyDeleteWhile a useful patterns, It's still not a true mixin as I would like, as you still have to have the signatures of the 'parents' added to the child class, and proxied to them, which depending on your intension of maintenance can be a good thing or a bad thing. If you have lots of children or lots of parents in flux this can get quite tedious. I suppose you can use runtime reflection to build a 'real' mixin, but I'm sure there's performance overhead on that way.
ReplyDeleteeverytime i read sometime like this it reminds me that java are too verbose...
ReplyDeletehow come people program in it?
Yeah, there are languages that are a lot more fun than Java. Then again, there are languages that are a lot less fun than Java as well :-)
ReplyDeleteAnother way is using dynaop (https://dynaop.dev.java.net/nonav/release/1.0-beta/manual/ch02s02.html).
ReplyDeleteChristian
Thanks Christian - I'll need to check out dynaop.
ReplyDeletehey jonathon, just got back from job interview asking this exact question - i wish i'd read it beforehand. nice post, i'll know how to do it next time :)
ReplyDeleteHi Anon - Ah, interesting.
ReplyDeleteHope the job hunt is going well.
Grr - code is obscured by the pictures in Firefox at my laptop's screen size. Good job this is about programming, not web design!
ReplyDeleteTrue mixins are in badly need by business applications. Unfortunately any approach I know has its own disadvantages. AOP is tricky. Delegating is copy-paste approach which suffers from non-inherited annotations and so on.
ReplyDeleteFrom the other hand it is not so difficult to implement mixins in Java compiler. With mixins there isn't collisions like multiple inheritance brought in C++. I think people that decide not to implement mixins in Java 7 are too far from understanding what are the benifits of mixins.
i could hardly call that beautiful, but i guess it is the closest you can get to MI in pure java code.
ReplyDelete@Anonymous - Yeah, perhaps beautiful isn't the right word to describe this code :-)
ReplyDelete