Created
October 26, 2017 18:43
-
-
Save cute-jumper/35a8605dd88f78f502db6d6ba7c3c152 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Type-safe builder pattern in Java with Phantom Types | |
*/ | |
public class PhantomType { | |
private static interface Filled {} | |
private static interface Empty {} | |
public static class Builder<T1, T2> { | |
private String name; | |
private String address; | |
private String email; | |
private Builder(String name, String address, String email) { | |
this.name = name; | |
this.address = address; | |
this.email = email; | |
} | |
public static Builder<Empty, Empty> getBuilder() { | |
return new Builder<Empty, Empty>(null, null, null); | |
} | |
// Mandatory field name | |
public Builder<Filled, T2> setName(String name) { | |
return new Builder<Filled, T2>(name, address, email); | |
} | |
// Mandatory field address | |
public Builder<T1, Filled> setAddress(String address) { | |
return new Builder<T1, Filled>(name, address, email); | |
} | |
// Optional field email | |
public Builder<T1, T2> setEmail(String email) { | |
return new Builder<T1, T2>(name, address, email); | |
} | |
} | |
private String name; | |
private String address; | |
private String email; | |
public PhantomType(Builder<Filled, Filled> builder) { | |
name = builder.name; | |
address = builder.address; | |
email = builder.email; | |
} | |
public static void main(String[] args) { | |
new PhantomType(Builder.getBuilder().setEmail("useless").setName("foo").setAddress("bar")); | |
// email is optional, i.e., ignoring it won't affect the compilation | |
new PhantomType(Builder.getBuilder().setAddress("bar").setName("foo")); | |
// The following two won't compile | |
//new PhantomType(Builder.getBuilder().setName("foo")); | |
//new PhantomType(Builder.getBuilder().setAddress("bar")); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment