Skip to content

Instantly share code, notes, and snippets.

@rjrjr
Last active March 4, 2023 22:10
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save rjrjr/7dcd53458a66a788505f1aeeea2c760d to your computer and use it in GitHub Desktop.
Save rjrjr/7dcd53458a66a788505f1aeeea2c760d to your computer and use it in GitHub Desktop.
Poor Man's Sealed Classes (visitor pattern)
/**
* For Java developers all excited by and jealous of Kotlin's sealed classes.
* Do this when you wish you could put parameters on an enum.
*/
public class PoorMan {
interface Event {
<T> T dispatch(EventHandler<T> handler);
}
interface EventHandler<T> {
T onEvent(ThingHappened event);
T onEvent(AnotherThingHappened event);
T onEvent(AThingWithParametersHappened event);
}
static final class ThingHappened implements Event {
static final ThingHappened INSTANCE = new ThingHappened();
private ThingHappened() {
}
@Override public <T> T dispatch(EventHandler<T> handler) {
return handler.onEvent(this);
}
}
static final class AnotherThingHappened implements Event {
static final AnotherThingHappened INSTANCE = new AnotherThingHappened();
private AnotherThingHappened() {
}
@Override public <T> T dispatch(EventHandler<T> handler) {
return handler.onEvent(this);
}
}
static final class AThingWithParametersHappened implements Event {
final String foo;
final String bar;
AThingWithParametersHappened(String foo, String bar) {
this.foo = foo;
this.bar = bar;
}
@Override public <T> T dispatch(EventHandler<T> handler) {
return handler.onEvent(this);
}
}
static void omgAnEvent(Event event) {
String whatHappened = event.dispatch(new EventHandler<String>() {
@Override public String onEvent(ThingHappened event) {
return "A Thing";
}
@Override public String onEvent(AnotherThingHappened event) {
return "A Nother Thing";
}
@Override public String onEvent(AThingWithParametersHappened event) {
return "Foo: " + event.foo + ", Bar: " + event.bar;
}
});
System.out.println(whatHappened);
}
public static void main(String... args) {
omgAnEvent(ThingHappened.INSTANCE);
omgAnEvent(AnotherThingHappened.INSTANCE);
omgAnEvent(new AThingWithParametersHappened("FOOOOO!", "bar"));
}
}
@rjrjr
Copy link
Author

rjrjr commented Sep 28, 2017

The omgAnEvent method illustrates what you do instead of a when / switch statement.

@rjrjr
Copy link
Author

rjrjr commented Sep 29, 2017

Updated to a) compile and b) add return values, to make this useful for pipelines.

@bangarharshit
Copy link

@rjrj Why not make the interface event private? It can't be instantiated from outside the file then.

@chetdeva
Copy link

Please rename the file to JavaSealedClass.java instead for code highlighting and better readability.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment