Quali modelli di progettazione fornirebbero una soluzione migliore a questo problema?

-1

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:

  1. 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.
  2. 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?

    
posta Javier Artiles 05.09.2018 - 00:36
fonte

2 risposte

4

Potresti eliminare sia l'interfaccia segnaposto che il downcasting aggiungendo un singolo metodo apply all'interfaccia e richiedendo a ogni classe di implementarlo.

public interface Operation {
    public Document apply(Document input);
}

Questo rende il tuo loop molto più semplice:

public OperationApplier {
    public Document apply(List<Operation> operations, Document inputDocument) {
        Document doc = inputDocument;
        for (Operation operation : operations) 
            doc = operation.apply(doc);
        }
        return doc;
    }
}

Quanto sopra richiede di spostare la logica apply fuori da OperationApplying e nella classe OperationX . Se non ritieni che sia una buona idea, puoi rendere apply un semplice passthrough.

public class OperationA implements Operation {
    private String paramA;
    private String paramB;

    public Document apply(Document input, OperationApplier applier) {
        return applier.apply(input);

}

E chiama con this :

for (Operation operation : operations) 
    doc = operation.apply(doc, this);
}
    
risposta data 05.09.2018 - 00:45
fonte
0

Stai descrivendo una tecnica nota come "orchestrazione" che è in realtà un modello di progettazione aziendale.

L'approccio di John Wu è corretto, l'operazione è il verbo e logicamente appartiene all'interfaccia. L'esempio di John è il classico pattern 'builder' in cui il documento viene passato in giro.

Se vuoi adottare un approccio diverso, puoi seguire l'approccio utilizzato da un motore di elaborazione delle regole. L'elaborazione basata su regole è utile per il flusso di lavoro, che è ciò che sembra speri di ottenere.

link

    
risposta data 05.09.2018 - 01:05
fonte

Leggi altre domande sui tag