Skip to content

Instantly share code, notes, and snippets.

@raphw
Created July 31, 2020 10:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save raphw/2ce8b94f4073a9885cef30a6af094f55 to your computer and use it in GitHub Desktop.
Save raphw/2ce8b94f4073a9885cef30a6af094f55 to your computer and use it in GitHub Desktop.
Example of generic delegation
public class Main {
public static void main(String[] args) {
Structure<Alpha, Alpha1, Alpha2> first = new First(new Alpha());
Structure<Beta, Beta1, Beta2> second = new Second(new Beta());
Structure<Object, Object, Object> template = new Template();
first.getValue().setValue(first.getValue().getValue());
//first.getValue().setValue(second.getValue().getValue());
//first.getValue().setValue(template.getValue().getValue());
//second.getValue().setValue(first.getValue().getValue());
second.getValue().setValue(second.getValue().getValue());
//second.getValue().setValue(template.getValue().getValue());
template.getValue().setValue(first.getValue().getValue());
template.getValue().setValue(second.getValue().getValue());
template.getValue().setValue(template.getValue().getValue());
}
interface Structure<SELF, DELEGATE, NESTED> {
Structure1<DELEGATE, NESTED> getValue();
void setValue(Structure1<? extends DELEGATE, ? extends NESTED> value);
}
interface Structure1<SELF, DELEGATE> {
Structure2<? extends DELEGATE> getValue();
void setValue(Structure2<? extends DELEGATE> value);
}
interface Structure2<SELF> {
String getValue();
void setValue(String value);
}
static class Alpha {
private Alpha1 value = new Alpha1();
public Alpha1 getValue() { return value; }
public void setValue(Alpha1 value) { this.value = value; }
}
static class Alpha1 {
private Alpha2 value = new Alpha2();
public Alpha2 getValue() { return value; }
public void setValue(Alpha2 value) { this.value = value; }
}
static class Alpha2 {
private String value = "foo";
public String getValue() { return value; }
public void setValue(String value) { this.value = value; }
}
static class Beta {
private Beta1 value = new Beta1();
public Beta1 getValue() { return value; }
public void setValue(Beta1 value) { this.value = value; }
}
static class Beta1 {
private Beta2 value = new Beta2();
public Beta2 getValue() { return value; }
public void setValue(Beta2 value) { this.value = value; }
}
static class Beta2 {
private String value = "bar";
public String getValue() { return value; }
public void setValue(String value) { this.value = value; }
}
static class First implements Structure<Alpha, Alpha1, Alpha2> {
final Alpha delegate;
public First(Alpha delegate) { this.delegate = delegate; }
@Override public Structure1<Alpha1, Alpha2> getValue() { return new First1(delegate.getValue()); }
@Override public void setValue(Structure1<? extends Alpha1, ? extends Alpha2> value) { delegate.setValue(((First1) value).delegate); }
}
static class First1 implements Structure1<Alpha1, Alpha2> {
final Alpha1 delegate;
public First1(Alpha1 delegate) { this.delegate = delegate; }
@Override public Structure2<Alpha2> getValue() { return new First2(delegate.getValue()); }
@Override public void setValue(Structure2<? extends Alpha2> value) { delegate.setValue(((First2) value).delegate); }
}
static class First2 implements Structure2<Alpha2> {
final Alpha2 delegate;
public First2(Alpha2 delegate) { this.delegate = delegate; }
@Override public String getValue() { return delegate.getValue(); }
@Override public void setValue(String value) { delegate.setValue(value); }
}
static class Second implements Structure<Beta, Beta1, Beta2> {
final Beta delegate;
public Second(Beta delegate) { this.delegate = delegate; }
@Override public Structure1<Beta1, Beta2> getValue() { return new Second1(delegate.getValue()); }
@Override public void setValue(Structure1<? extends Beta1, ? extends Beta2> value) { delegate.setValue(((Second1) value).delegate); }
}
static class Second1 implements Structure1<Beta1, Beta2> {
final Beta1 delegate;
public Second1(Beta1 delegate) { this.delegate = delegate; }
@Override public Structure2<Beta2> getValue() { return new Second2(delegate.getValue()); }
@Override public void setValue(Structure2<? extends Beta2> value) { delegate.setValue(((Second2) value).delegate); }
}
static class Second2 implements Structure2<Beta2> {
final Beta2 delegate;
public Second2(Beta2 delegate) { this.delegate = delegate; }
@Override public String getValue() { return delegate.getValue(); }
@Override public void setValue(String value) { delegate.setValue(value); }
}
static class Template implements Structure<Object, Object, Object> {
private Structure1<?, ?> value = new Template1();
@Override @SuppressWarnings("unchecked") public Structure1<Object, Object> getValue() { return (Structure1<Object, Object>) value; }
@Override public void setValue(Structure1<?, ?> value) { this.value = value; }
}
static class Template1 implements Structure1<Object, Object> {
private Structure2<?> value = new Template2();
@Override @SuppressWarnings("unchecked") public Structure2<Object> getValue() { return (Structure2<Object>) value; }
@Override public void setValue(Structure2<?> value) { this.value = value; }
}
static class Template2 implements Structure2<Object> {
private String value = "qux";
@Override public String getValue() { return value; }
@Override public void setValue(String value) { this.value = value; }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment