Skip to content

Instantly share code, notes, and snippets.

@joshmoore
Created December 6, 2016 11:42
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 joshmoore/8108f68055da27d4560951ad5ac921fc to your computer and use it in GitHub Desktop.
Save joshmoore/8108f68055da27d4560951ad5ac921fc to your computer and use it in GitHub Desktop.
Various Options API possibilities
public class Options {
public static void main(String[] args) {
new Consumer1();
new Consumer2();
new Consumer3();
new Consumer4();
new Consumer5();
new Consumer6();
new Consumer7();
new Consumer8();
}
}
//
// 1. Old state
//
interface MetadataOptions1 {
}
class DefaultMetadataOptions1 implements MetadataOptions1 {
}
class Base1 {
MetadataOptions1 getMetadataOptions() {
return new DefaultMetadataOptions1();
}
}
class Consumer1 extends Base1 {
Consumer1() {
getMetadataOptions();
System.out.println("Consumer1: can't do an k/v stuff here");
}
}
//
// 2. The current 5.3 state
//
interface MetadataOptions2 {
}
class FormatOptions2 {
java.util.Properties properties = new java.util.Properties();
}
class DefaultMetadataOptions2 extends FormatOptions2 implements MetadataOptions2 {
}
class Base2 {
MetadataOptions2 getMetadataOptions() {
return new DefaultMetadataOptions2();
}
}
class Consumer2 extends Base2 {
Consumer2() {
MetadataOptions2 opt = getMetadataOptions();
if (opt instanceof FormatOptions2) {
((FormatOptions2) opt).properties.getProperty("foo", "bar");
}
System.out.println("Consumer2: can do k/v if it happens to be a format options");
}
}
//
// 3. The CZI PR
//
interface MetadataOptions3 {
}
class FormatOptions3 {
java.util.Properties properties = new java.util.Properties();
}
class DefaultMetadataOptions3 extends FormatOptions3 implements MetadataOptions3 {
}
class Base3 {
MetadataOptions3 getMetadataOptions() {
return new DefaultMetadataOptions3();
}
}
class Consumer3 extends Base3 {
Consumer3() {
DefaultMetadataOptions3 ops = (DefaultMetadataOptions3) getMetadataOptions(); // Can't do any k/v here
System.out.println("Consumer3: this is a bad assumption");
}
}
//
// 4. Subclassing with deprecation
//
@Deprecated
interface MetadataOptions4 {
}
interface FormatOptions4 extends MetadataOptions4 {
java.util.Properties getProperties();
}
class DefaultMetadataOptions4 implements FormatOptions4 {
public java.util.Properties getProperties() {
return new java.util.Properties();
}
}
class Base4 {
@Deprecated
MetadataOptions4 getMetadataOptions() {
return new DefaultMetadataOptions4();
}
FormatOptions4 getFormatOptions() {
return new DefaultMetadataOptions4();
}
}
class Consumer4 extends Base4 {
Consumer4() {
MetadataOptions4 mops = getMetadataOptions(); // Can't do any k/v here
FormatOptions4 fops = getFormatOptions(); // Can do any k/v here
System.out.println("Consumer4: use deprecation");
}
}
//
// 5. Breaking interface addition
//
interface FormatOptions5 {
java.util.Properties getProperties();
}
interface MetadataOptions5 extends FormatOptions5 {
}
class DefaultMetadataOptions5 implements MetadataOptions5 {
public java.util.Properties getProperties() {
return new java.util.Properties();
}
}
class Base5 {
MetadataOptions5 getMetadataOptions() {
return new DefaultMetadataOptions5();
}
}
class Consumer5 extends Base5 {
Consumer5() {
MetadataOptions5 mops = getMetadataOptions(); // Can do any k/v here
System.out.println("Consumer5: use breaking");
}
}
//
// 6. Use a subinterface return type
//
interface MetadataOptions6 {
}
interface FormatOptions6 extends MetadataOptions6 {
java.util.Properties getProperties();
}
class DefaultMetadataOptions6 implements FormatOptions6 {
public java.util.Properties getProperties() {
return new java.util.Properties();
}
}
class Base6 {
FormatOptions6 getMetadataOptions() {
return new DefaultMetadataOptions6();
}
}
// Not working yet:
//class Other6 extends Base6 {
// MetadataOptions6 getMetadataOptions() {
// return new DefaultMetadataOptions6();
// }
//}
class Consumer6 extends Base6 {
Consumer6() {
MetadataOptions6 mops = getMetadataOptions(); // Can't do any k/v here
FormatOptions6 fops = getMetadataOptions(); // Can do any k/v here
System.out.println("Consumer6: use a different return type");
}
}
//
// 7. Use a new implementation
//
interface MetadataOptions7 {
}
class DynamicMetadataOptions7 implements MetadataOptions7 {
public java.util.Properties getProperties() {
return new java.util.Properties();
}
}
class Base7 {
MetadataOptions7 getMetadataOptions() {
return new DynamicMetadataOptions7();
}
}
class Other7 extends Base7 {
MetadataOptions7 getMetadataOptions() {
return new DynamicMetadataOptions7();
}
}
class Consumer7 extends Base7 {
Consumer7() {
MetadataOptions7 mops = getMetadataOptions(); // Can't do any k/v here
if (mops instanceof DynamicMetadataOptions7) {
DynamicMetadataOptions7 fops = (DynamicMetadataOptions7) mops; // Can do any k/v here
}
System.out.println("Consumer7: use a different implementation");
}
}
//
// 8. After 7, add methods to interface
//
interface MetadataOptions8 {
java.util.Properties getProperties();
}
class DynamicMetadataOptions8 implements MetadataOptions8 {
public java.util.Properties getProperties() {
return new java.util.Properties();
}
}
class Base8 {
MetadataOptions8 getMetadataOptions() {
return new DynamicMetadataOptions8();
}
}
class Other8 extends Base8 {
MetadataOptions8 getMetadataOptions() {
return new DynamicMetadataOptions8();
}
}
class Consumer8 extends Base8 {
Consumer8() {
MetadataOptions8 mops = getMetadataOptions(); // Can't do any k/v here
if (mops instanceof DynamicMetadataOptions8) {
DynamicMetadataOptions8 dops = (DynamicMetadataOptions8) mops; // Can do any k/v here
}
System.out.println("Consumer8: then add methods to interface");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment