JavaScript: gestire i comandi di una CLI con if, else e switch

by Anastasia P.
SHARE
JavaScript: gestire i comandi di una CLI con if, else e switch
© Guida-HTML5.it

Introduzione

Quando si sviluppa uno script da riga di comando, è necessario interpretare ciò che l’utente scrive e decidere quale operazione eseguire. Un programma può ricevere comandi come start, stop, status oppure help. Le strutture condizionali di JavaScript sono ideali per gestire questo tipo di flusso.

In questo tutorial costruiremo un semplice gestore di comandi per una piccola applicazione. Useremo:

  • if per controllare condizioni generali, come l’assenza di un comando;
  • else per definire un comportamento alternativo;
  • switch per confrontare il comando con una serie di valori conosciuti;
  • funzioni separate per mantenere il codice leggibile e facilmente estendibile.

L’obiettivo non è soltanto imparare la sintassi, ma capire come scegliere la struttura condizionale più adatta in uno scenario reale.

Codice completo

const statoServizio = {
  attivo: false,
  ultimaAzione: null
};

function mostraAiuto() {
  console.log(`
Comandi disponibili:
  start   Avvia il servizio
  stop    Arresta il servizio
  status  Mostra lo stato corrente
  help    Mostra questo messaggio
  exit    Termina l´applicazione
  `);
}

function avviaServizio() {
  if (statoServizio.attivo) {
    console.log("Il servizio è già attivo.");
  } else {
    statoServizio.attivo = true;
    statoServizio.ultimaAzione = "start";
    console.log("Servizio avviato correttamente.");
  }
}

function arrestaServizio() {
  if (!statoServizio.attivo) {
    console.log("Il servizio è già fermo.");
  } else {
    statoServizio.attivo = false;
    statoServizio.ultimaAzione = "stop";
    console.log("Servizio arrestato correttamente.");
  }
}

function mostraStato() {
  if (statoServizio.attivo) {
    console.log("Stato: attivo");
  } else {
    console.log("Stato: fermo");
  }

  if (statoServizio.ultimaAzione === null) {
    console.log("Non è stata ancora eseguita alcuna azione.");
  } else {
    console.log(`Ultima azione: ${statoServizio.ultimaAzione}`);
  }
}

function gestisciComando(input) {
  const comando = input.trim().toLowerCase();

  if (comando === "") {
    console.log("Inserisci un comando.");
    return;
  }

  switch (comando) {
    case "start":
      avviaServizio();
      break;

    case "stop":
      arrestaServizio();
      break;

    case "status":
      mostraStato();
      break;

    case "help":
      mostraAiuto();
      break;

    case "exit":
      console.log("Chiusura dell´applicazione.");
      break;

    default:
      console.log(
        `Comando "${comando}" non riconosciuto. Scrivi "help" per l´elenco.`
      );
  }
}

// Esempi di utilizzo
gestisciComando("status");
gestisciComando("start");
gestisciComando("start");
gestisciComando("status");
gestisciComando("stop");
gestisciComando("unknown");

Spiegazione

Normalizzare il comando ricevuto

La funzione gestisciComando riceve una stringa. Prima di eseguire qualsiasi controllo, la normalizza:

const comando = input.trim().toLowerCase();

trim() rimuove gli spazi all’inizio e alla fine, mentre toLowerCase() rende il comando indipendente dalle maiuscole. In questo modo, valori come " start ", "START" e "start" vengono interpretati allo stesso modo.

Usare if per i controlli preliminari

Il primo if verifica se l’utente ha inserito una stringa vuota:

if (comando === "") {
  console.log("Inserisci un comando.");
  return;
}

Questa è una condizione preliminare: se non esiste un comando, non ha senso continuare con il resto della funzione. L’istruzione return interrompe immediatamente l’esecuzione.

All’interno delle funzioni avviaServizio e arrestaServizio, if e else gestiscono due situazioni opposte. Per esempio, un servizio già attivo non deve essere avviato nuovamente:

if (statoServizio.attivo) {
  console.log("Il servizio è già attivo.");
} else {
  statoServizio.attivo = true;
}

La condizione descrive una regola del dominio: se il servizio è attivo, informa l’utente; altrimenti esegui l’avvio.

Usare switch per i comandi disponibili

switch è particolarmente leggibile quando bisogna confrontare una stessa variabile con molti valori possibili:

switch (comando) {
  case "start":
    avviaServizio();
    break;

  case "stop":
    arrestaServizio();
    break;

  default:
    console.log("Comando non riconosciuto.");
}

Ogni case rappresenta un comando. L’istruzione break impedisce l’esecuzione dei casi successivi. Senza break, JavaScript continuerebbe nel caso seguente: questo comportamento, chiamato fall-through, è utile solo quando viene usato intenzionalmente.

Il blocco default funziona come alternativa finale e gestisce tutti i comandi non previsti.

Raggruppare la logica in funzioni

Lo switch non contiene direttamente tutta la logica dell’applicazione. Ogni caso delega il lavoro a una funzione specifica. Questa separazione rende il codice più comprensibile e permette di testare le singole operazioni in modo indipendente.

Best practice

  • Normalizza gli input: usa trim() e, quando opportuno, toLowerCase() prima dei confronti.
  • Gestisci sempre l’input non valido: un caso default evita che i comandi sconosciuti vengano ignorati senza spiegazioni.
  • Inserisci break nei case: controlla che ogni caso termini correttamente, a meno che il fall-through non sia intenzionale.
  • Usa funzioni con una responsabilità chiara: una funzione dovrebbe avviare, fermare o descrivere il servizio, non fare tutte queste cose insieme.
  • Preferisci confronti espliciti: usa === invece di == per evitare conversioni automatiche di tipo.
  • Proteggi le funzioni dagli input imprevisti: se il valore può non essere una stringa, controllalo prima di chiamare trim().
  • Non abusare di switch: per poche condizioni semplici, un if...else può essere più diretto. Switch è invece comodo quando confronti una stessa espressione con molti valori.

Riepilogo

Le strutture condizionali permettono di trasformare un input in un’azione concreta. In un gestore di comandi:

  • if controlla condizioni specifiche, come un comando vuoto o lo stato attuale del servizio;
  • else definisce cosa fare quando la condizione principale non è verificata;
  • switch seleziona rapidamente l’operazione associata a un comando;
  • default gestisce i valori sconosciuti;
  • le funzioni mantengono separati il riconoscimento del comando e l’esecuzione dell’azione.

Questo schema può essere riutilizzato per script di automazione, strumenti di sviluppo, utility da terminale e applicazioni che ricevono comandi testuali.

Approfondisci con risorse ufficiali

SHARE