A problem I've come across and never really had a good answer for, is: what is the correct design pattern for creating or returning an object from another object, or multiple objects?
Traditionally I've just created a Factory
and had the source as a argument:
#!/usr/bin/env groovy
class Foo {
String bar
}
class FooFactory {
Foo createFoo(Map mapWithBar) {
Foo foo = new Foo()
foo.bar = mapWithBar.get('bar')
foo
}
}
assert 'Hello, World!' == new FooFactory().createFoo(['bar': 'Hello, World!']).bar
Is factory really the correct name for this pattern?
What happens when you want to encapsulate pseudo-creational logic that has multiple possible sources, or possibly the object is even already created?
For example, say if bar
is in a list of Strings
(i.e. cli args), set bar
from that, otherwise if Foo
already exists in some data structure, use that foo
, otherwise create a new Foo
with a default bar
:
#!/usr/bin/env groovy
class Foo {
String bar
}
class FooFactory {
Foo createFoo(List<String> args, Map mapContainingFoo, String defaultBar) {
if (args?.size > 0) {
def foo = new Foo();
foo.bar = args[0];
return foo;
} else if (mapContainingFoo?.containsKey('foo')) {
return mapContainingFoo.get('foo');
} else {
Foo foo = new Foo();
foo.bar = defaultBar;
return foo;
}
}
}
def fooFactory = new FooFactory();
assert 'args' == fooFactory.createFoo(['args'], ['foo': new Foo(bar: 'fromMap')], 'default').bar
assert 'fromMap' == fooFactory.createFoo(null, ['foo': new Foo(bar: 'fromMap')], 'default').bar
assert 'default' == fooFactory.createFoo(null, null, 'default').bar
Is there a better design pattern to encapsulate this logic? Is Factory
the correct term? Is it even still a Factory
since it isn't necessarily creating Foo
?
Note that I'm only using groovy for ease of demonstration, I'm mainly concerned with the design pattern and not an idiomatic way of doing this in groovy.