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.