Ho esaminato varie definizioni del modello di builder e, sebbene esistano definizioni diverse, tendono a concentrarsi sull'ampia definizione di costruzione incrementale. Tuttavia, sembra che la maggior parte degli esempi di builder che ho mai visto essenzialmente costruisca solo tipi "value" con il concatenamento del metodo.
Ho trovato, tuttavia, che a volte può essere più utile utilizzare un tipo di modello completamente diverso nel builder per svolgere attività aggiuntive. Quindi, oltre a quello che la gente si aspetta in genere da un costruttore, questo costruttore:
- Può nascondere i dettagli del tipo che si sta creando
- Incorporare la logica di compilazione complessa nel builder
- Uso dello stesso builder per creare più tipi simili
Ho messo insieme un semplice esempio di una variante di builder che ho creato in Java e che speriamo possa dimostrare meglio le idee. (Nota: 1 non è molto ben dimostrato poiché richiederebbe molto più codice per illustrare)
class FamiliesBuilder {
final Map<String, List<String>> familyMap = new HashMap<>();
String lastName;
List<String> familyList;
FamiliesBuilder newFamily(String lastName) {
this.familyList = this.familyMap.getOrDefault(lastName, new LinkedList<>());
this.familyMap.put(lastName, this.familyList);
this.lastName = lastName;
return this;
}
FamiliesBuilder addFamilyMember(String firstName) {
this.familyList.add(firstName);
return this;
}
Map<String, List<Person>> buildLastNameLookup() {
final Map<String, List<Person>> res = new HashMap<>();
for (Entry<String, List<String>> e : this.familyMap.entrySet()) {
final String personLastName = e.getKey();
final List<Person> people = new LinkedList<>();
for (String firstName : e.getValue()) {
people.add(new Person(firstName, personLastName));
}
res.put(e.getKey(), people);
}
return res;
}
List<Person> build() {
List<Person> people = new LinkedList<>();
for (Entry<String, List<String>> e : this.familyMap.entrySet()) {
String personLastName = e.getKey();
for (String personFirstName : e.getValue()) {
people.add(new Person(personFirstName, personLastName));
}
}
return people;
}
class Person {
private String firstName;
private String lastName;
private Person(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
}
public static void main(String... args) {
// Usage example
List<Person> people = new FamiliesBuilder()
.newFamily("Doe")
.addFamilyMember("John")
.addFamilyMember("Jane")
.newFamily("Smith")
.addFamilyMember("Tom")
.build();
}
}
Sono preoccupato che questa variante sia troppo lontana dal classico modello di builder che chiamarlo builder può essere fonte di confusione e, in tal caso, mi chiedo se ci siano modelli o tecniche di design riconoscibili che realizzano un'attività simile.