9

Considerate che avete ottenuto diverse convalide. Queste convalide dovrebbero avere effetto solo se l'oggetto da ispezionare è di un certo tipo. Perché dovrei usare una catena di responsabilità su una dichiarazione di switch?Perché dovrei usare una catena di responsabilità su una dichiarazione di commutazione

Esempio con la catena di responsabilità

public class Executor { 

@Inject 
private ValidatorFactory validatorFactory; 

public void execute(Konfiguration konfig) { 
    List<Statement> statements = konfig.getStatements(); 
    AbstractValidator validator = validatorFactory.create(); 
    for (Statement statement : statements) { 
     if (validator.validate(statement.getType())) { 
      crudService.execute(statement.getSql()); 
     } 
    } 
} 

Il validatorFactory crea la catena di validatori. Un validatore sarebbe simile

public class AddPrimaryKeyValidator extends AbstractValidator { 

@Override 
public boolean validate(Statement statement) { 
    if (SqlType.ADD_PK.getTyp().equals(statement.getType())) { 
     return doesTableAndPrimaryKeyExist(statement.getTabName()); 
    } 
    return successor.validate(statement); 
} 

Esempio con switch-dichiarazione

public void execute(Konfiguration konfig) { 
    List<Statement> statements = konfig.getStatements(); 
    for (Statement statement : statements) { 
     switch (statement.getType()) { 
     case "ADD_PK": 
      if (doesTableAndPrimaryKeyExist(statement.getTabName())) { 
       frepCrudService.execute(statement.getSql()); 
      } 
      // more cases 
     } 
    } 
} 

risposta

8

Perché in una catena di responsabilità che non c'è bisogno di sapere chi fa cosa in attacco nel chiamante. La logica di decidere quando stai per eseguire il tuo pezzo di codice in una catena è di tua proprietà e il resto del codice può ignorarlo. Ciò consente di incapsulare la logica specifica nel posto giusto. I filtri servlet sono un buon esempio di questo

0

Sembra uno strano motivo per utilizzare una catena di responsabilità. Fondamentalmente stai costruendo una catena solo per creare un elenco dinamico di istruzioni if, che probabilmente non sono comunque dinamiche poiché sono sicuro che hai codificato l'inizializzazione della catena con un validatore per istruzione.

Credo che questa catena di responsabilità non sia lo schema giusto per questo. Dovresti sostituire se le dichiarazioni da polimorfismo invece.

Ad esempio, se si dispone delle classi specializzate Statement, è sufficiente eseguire statement.validate(). Statement non deve convalidare se stesso se non si desidera, può solo sapere quale validatore utilizzare internamente e delegare la convalida ad esso.

Se non si dispone di classi di istruzioni specializzate, è possibile richiedere direttamente alla fabbrica il validatore corretto anziché costruire l'intera catena.

+0

Intendi qualcosa come AbstractValidator validator = validatorFactory.create (statement.getType()) ;? La fabbrica stessa lavora quindi con il case-interruttore, per decidere quale validatore costruire? – Chris311

+0

@ Chris311 Sì, questa è un'opzione. Ma probabilmente sarebbe preferibile avere classi 'Statement' specializzate (a meno che non differiscano solo per il loro tipo). Puoi anche lavorare con un 'StatementValidationService' invece di chiedere direttamente un validatore. In questo modo il client può solo 'validationService.validate (statement)' e internamente il validationService sa quale strategia usare. Puoi usare una 'Mappa' internamente per legare i tipi alle strategie se vuoi aggiungere dinamicamente nuovi tipi. – plalx

+0

Non desidero classi di istruzioni diverse perché sono associate a un'entità. Ho trovato un'altra soluzione molto carina: The Factory inietta un'interfaccia di validazione con @Any. I validatori sanno quando sono applicabili e poi si restituiscono. – Chris311