Skip to content

Instantly share code, notes, and snippets.

@int128
Last active August 29, 2015 13:59
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 int128/10613715 to your computer and use it in GitHub Desktop.
Save int128/10613715 to your computer and use it in GitHub Desktop.
Create an immutable object by a closure instead of the hash constructor
class ImmutableFactory<T> {
private final Map<String, Object> propertiesMap = [:]
private final Class<T> clazz
def ImmutableFactory(Class<T> clazz) {
this.clazz = clazz
}
T create() {
clazz.metaClass.invokeConstructor(propertiesMap)
}
Object getProperty(String property) {
assert clazzAcceptsProperty(property)
propertiesMap[property]
}
void setProperty(String property, Object newValue) {
assert clazzAcceptsProperty(property)
propertiesMap[property] = newValue
}
private boolean clazzAcceptsProperty(String property) {
clazz.metaClass.properties.find { it.name == property }
}
static <T> T create(Class<T> clazz, Closure closure) {
def factory = new ImmutableFactory(clazz)
factory.with(closure)
factory.create()
}
}
@groovy.transform.Immutable
class A {
int x
int y
}
def factory = new ImmutableFactory(A)
factory.with {
x = 100
y = 200
}
def a1 = factory.create()
assert a1 == new A(x: 100, y: 200)
def a2 = ImmutableFactory.create(A) {
x = 300
y = 400
}
assert a2 == new A(x: 300, y: 400)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment