Ho un oggetto documento e un elenco di operazioni che possono essere applicate a quel documento in sequenza. I tipi di operazioni sono noti in anticipo, ma non i loro parametri, l'ordine delle operazioni o il loro numero. Ad esempio, potrebbe esserci un DB dal quale estrarre un elenco specifico di operazioni e i parametri corrispondenti per un dato documento.
La soluzione che ho scritto in Java è simile alla seguente:
public interface Operation {
}
public class OperationA implements Operation {
private String paramA;
private String paramB;
}
public class OperationB implements Operation {
private String paramA;
private String paramB;
private String paramC;
}
public OperationApplier {
public Document apply(List<Operation> operations, Document inputDocument) {
Document transformedDocument = inputDocument;
for (Operation operation : operations) {
if (operation instanceof OperationA) {
OperationA operationA = (OperationA) operation;
transformedDocument = apply(operationA, document);
} else if (operation instanceof OperationB) {
OperationB operationB = (OperationB) operation;
transformedDocument = apply(operationB, document);
}
}
return transformedDocument;
}
}
private Document apply(OperationA operation, Document document) {
...
}
private Document apply(OperationB operation, Document document) {
...
}
Ora per applicare un elenco di operazioni su un documento che possiamo fare:
OperationApplier operationApplier = new OperationApplier();
List<Operation> operations = Arrays.asList(
new OperationA("foo", "bar"),
new OperationB("foo", "bar", "baz"),
new OperationA("hoge", "piyo")
);
Document inputDocument = ...;
Document outputDocument = operationApplier(operations, inputDocument);
Fondamentalmente vedo due odori nella soluzione che ho implementato sopra:
- L'interfaccia vuota
Operation
è lì solo per consentire la costruzione di un elenco di operazioni, ma altrimenti non contiene alcun contratto condiviso tra le implementazioni operative. - L'uso di
instanceof
e downcasting, che sono considerati anche cattive pratiche in Java.
Ci sono degli schemi di progettazione che dovrei considerare per migliorare l'implementazione sopra? Oltre ai due odori che ho citato, vedi dei problemi sostanziali con la soluzione che ho adottato?