Un problema che ho riscontrato e che non ha mai avuto una buona risposta è: qual è il modello di progettazione corretto per creare o restituire un oggetto da un altro oggetto o più oggetti?
Tradizionalmente ho appena creato un Factory
e ho avuto il sorgente come argomento:
#!/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
La fabbrica è davvero il nome corretto per questo modello?
Che cosa succede quando vuoi incapsulare la logica pseudo-creazionale che ha più fonti possibili, o forse l'oggetto è già stato creato?
Ad esempio, supponi che bar
sia in list of Strings
(cioè cli args), imposta bar
da quello, altrimenti se Foo
esiste già in qualche struttura dati, usa quel foo
, altrimenti crea un nuovo Foo
con un bar
predefinito:
#!/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
Esiste un modello di progettazione migliore per incapsulare questa logica? Factory
è il termine corretto? È ancora pari a Factory
poiché non sta necessariamente creando Foo
?
Nota che sto usando solo groovy per facilità di dimostrazione, sono principalmente interessato al modello di design e non a un modo idiomatico di farlo in groovy.