La funzione My checker deve restituire sia un booleano che un messaggio

14

Ho una funzione di controllo del valore, qualcosa di simile a una funzione di controllo del numero di carta di credito, che viene passata in una stringa e deve verificare che il valore sia del formato corretto.

Se è il formato giusto, è necessario restituire true.

Se non è il formato giusto, è necessario restituire false e anche dirci cosa c'è di sbagliato nel valore.

La domanda è: qual è il modo più bello per raggiungere questo obiettivo?

Ecco alcune soluzioni:

1. Utilizza i codici di ritorno intero / enum per indicare i significati:

String[] returnCodeLookup = 
[
"Value contains wrong number of characters, should contain 10 characters",
"Value should end with 1", 
"Value should be a multiple of 3"
]

private int valueChecker(String value)
{
    /*check value*/
    return returnCode;
}

rc = checkValue(valueToBeChecked);
if rc == 0
{
    /*continue as normal*/
}
else
{
    print("Invalid value format: ") + returnCodeLookup[rc];
}

Questa soluzione non mi piace perché richiede l'implementazione dal lato del chiamante.

2. Crea una classe returnCode

Class ReturnCode()
{
    private boolean success;
    private String message;

    public boolean getSuccess()
    {
        return this.success;
    }

    public String getMessage()
    {
        return this.message; 
    }
}

private ReturnCode valueChecker(String value)
{
    /*check value*/
    return returnCode;
}

rc = checkValue(valueToBeChecked);
if rc.getSuccess()
{
    /*continue as normal*/
}
else
{
    print("Invalid value format: ") + rc.getMessage();
}

Questa soluzione è ordinata, ma sembra eccessivo / reinventare la ruota.

3. Usa le eccezioni.

private boolean valueChecker(String value)
{
    if int(value)%3 != 0 throw InvalidFormatException("Value should be a multiple of 3";
    /*etc*/
    return True;
}

try {
rc = checkValue(valueToBeChecked);
}

catch (InvalidFormatException e)
{
     print e.toString();
}

Sono tentato di usare questa soluzione, ma mi viene detto che non devi usare eccezioni per la logica di business.

    
posta dwjohnston 23.02.2015 - 00:00
fonte

3 risposte

14

Utilizza un oggetto di ritorno più complesso che racchiuda entrambe le preoccupazioni. Esempio:

public interface IValidationResult {
  boolean isSuccess();
  String getMessage();
}

Questo ha diversi vantaggi:

  1. Restituisce più pezzi di dati correlati in un unico oggetto.
  2. Spazio per l'espansione se è necessario aggiungere ulteriori dati in futuro.
  3. Nessuna dipendenza dall'accoppiamento temporale: è possibile convalidare più input e non sovraccaricare il messaggio come nell'altra risposta. Puoi controllare i messaggi in qualsiasi ordine, anche attraverso i thread.

In realtà ho usato questo disegno specifico prima, in applicazioni in cui una convalida può essere più che semplicemente vera o falsa. Forse è necessario un messaggio dettagliato, o solo una parte dell'input non è valida (ad esempio un modulo con dieci elementi potrebbe avere solo uno o due campi non validi). Utilizzando questo design, puoi facilmente soddisfare tali requisiti.

    
risposta data 23.02.2015 - 03:36
fonte
2

Nessuno dei precedenti, usa una classe ValueChecker

Prima un'interfaccia per darti flessibilità:

public interface IValueChecker {
    public boolean checkValue(String value);
    public String getLastMessage();
}

Quindi implementa tutti i valuechecker necessari:

public class MyVeryEspecificValueChecker implements IValueChecker {
    private String lastMessage="";
    @Override
    public boolean checkValue(String value) {
        boolean valid=false;
        // perform check, updates "valid" and "lastMessage"
        return valid;
    }
    @Override
    public String getLastMessage() {
        return lastMessage;
    }
}

Esempio di codice cliente:

public class TestValueChecker {
    public static void main(String[] args) {
        String valueToCheck="213123-YUYAS-27163-10";
        IValueChecker vc = new MyVeryEspecificValueChecker();
        vc.checkValue(valueToCheck);
        System.out.println(vc.getLastMessage());
    }
}

Ha il vantaggio che puoi avere molti diversi correttori di valori.

    
risposta data 23.02.2015 - 00:24
fonte
1

La mia risposta estende l'approccio di @ Snowman. Fondamentalmente, ogni convalida, ogni regola aziendale e ogni logica aziendale dovrebbero essere in grado di dare una risposta - almeno, nelle applicazioni web. Questa risposta, a sua volta, viene visualizzata da un chiamante. Questo mi ha portato alla seguente interfaccia (è php, ma la domanda è di natura indipendente dalla lingua):

interface Action
{
    /**
     * @param Request $request
     * @throws RuntimeException
     * @return Response
     */
    public function act(Request $request);
}

La creazione di un operatore di commutazione che agisce come un'espressione, non come un'istruzione, porta al servizio dell'applicazione con un aspetto simile a questo:

class MyApplicationService implements Action
{
    private $dataStorage;

    public function __construct(UserDataStorage $dataStorage)
    {
        $this->dataStorage = $dataStorage;
    }

    public function act(Request $request)
    {
        return
            (new _SwitchTrue(
                new _Case(
                    new EmailIsInvalid(),
                    new EmailIsInvalidResponse()
                ),
                new _Case(
                    new PasswordIsInvalid(),
                    new PasswordIsInvalidResponse()
                ),
                new _Case(
                    new EmailAlreadyRegistered($this->dataStorage),
                    new EmailAlreadyRegisteredResponse()
                ),
                new _Default(
                    new class implements Action
                    {
                        public function act(Request $request)
                        {
                            // business logic goes here

                            return new UserRegisteredResponse();
                        }
                    }
                )
            ))
                ->act($request)
            ;
    }
}
    
risposta data 30.11.2017 - 19:17
fonte

Leggi altre domande sui tag