Domanda

Ho un'entità, pari a un compito, che può avere più stati. Il "compito" può essere sia in una, passata, o stato fallito in sospeso. Ognuno di questi Stati membri dovranno anche alcuni dati univoci. Per esempio, in uno stato fallito l'entità dovrebbe avere un motivo per il fallimento, nello stato in sospeso che dovrebbe avere una scadenza per la valutazione, ecc.

Mentre il sopra mi porta a pensare che dovrei avere un oggetto distinto per rappresentare ogni stato, l'ID di fondo per l'entità dovrebbe rimanere lo stesso, mi spinge di nuovo verso il pensiero di questo come un singolo oggetto.

Inoltre, la transizione da uno stato all'altro richiede una certa logica. A "in sospeso" compito transizione ad un "passato" Stato saranno trattati in modo diverso rispetto a "Failed" compito fare la stessa transizione.

Se le rappresentazioni per ogni stato erano esattamente gli stessi mi basta usare una proprietà primitiva e da fare con esso. Tuttavia, dal momento che i diversi stati hanno rappresentazioni leggermente diverse, ho lottato per capire il modo migliore per modellare questo. La logica per governare lo stato interno è sempre un po 'disordinato così ho pensato di fare un passo indietro e riconsiderare. Ogni pensiero?

Sto usando C # anche se mi piacerebbe prendere in considerazione questa lingua agnostico.

È stato utile?

Soluzione

Quando ho letto questa domanda, la mia risposta è stata di utilizzare un'enumerazione per definire lo stato. Dopo rileggendolo, però, vorrei suggerire uno dei seguenti modi:

  1. Implementare ogni attività come una classe separata (PendingTask, PassedTask, ...) con lo stesso genitore, e un costruttore che accetta un compito di qualsiasi tipo che viene prima di quello stato.
  2. Implementare un compito, e creare una nuova classe TaskStateData con le classi figlio per i dati necessari per ogni stato.
  3. Implementare un compito, ma hanno un metodo separato per cambiare lo stato per ogni tipo di stato con i parametri per le caratteristiche supplementari necessari per lo Stato

Suggerisco queste soluzioni per garantire l'integrità dei dati.

Altri suggerimenti

Vuoi utilizzare un approccio puro Object-Oriented ha aspetti negativi. A meno che non si pensa di avere a che fare un sacco di gestione di codice polimorfi, evitare che rappresenta lo stato del vostro codice categoria dominio utilizzando direttamente il polimorfismo. Ho optato per un approccio più ibrido. I diversi stati hanno bisogno di essere modellato come un'eredità albero padre / figlio separato. Inizia con un abstract MyState classe di base che hanno come figli MyState1, MyState2 e MyState3. (Vedi risposta di Jeffrey per un esempio.

L'entità che necessita suo stato monitorato ha un attributo 'attuale stato' che è di tipo MyState. quando l'entità cambia stato è un'assegnazione semplice o setter () per modificarlo. È possibile costruire istanze singleton di ogni stato se lo si desidera, o la costruzione di nuove istanze per ogni cambiamento di stato. Dipende da quanto spesso i cambiamenti di stato e quanti oggetti stanno avendo il loro stato rintracciato. Se i numeri diventano troppo grandi si può considerare l'approccio Singleton.

  

Il "compito" può essere sia in una, passata, o stato fallito in sospeso.   A "in sospeso" compito transizione ad un "passato" Stato saranno trattati in modo diverso rispetto a "Failed" compito fare la stessa transizione.

Questa sembra una collezione piuttosto strana di stati. Mi aspetto un compito da prendere un po 'di tempo per l'esecuzione, in modo transizione da attesa per l'esecuzione di allora o passare o fallire, e le attività che non eseguono prima del tempo si esaurisce per scadere. Se c'è anche un passaggio dal non è riuscito a failed-e-scaduto quindi che potrebbe aggiungere un altro stato.

Disegna una macchina a stati per trovare gli stati.

In primo luogo, avete bisogno di modellare gli stati strutturalmente? Sarebbe un / bandierina scaduto in attesa, un tempo previsto e di conseguenza fare (con il fallimento e il successo come i due sotto-tipi di risultato)? Che cosa i clienti del compito ha bisogno da esso?

In secondo luogo, stai interagendo con un compito o un programmatore? Non è raro per dare una descrizione compito di uno scheduler e per tornare un futuro, che può essere interrogato sul risultato del compito. Ma il compito in sé non è esposto, solo se è completa e il risultato. Se avete bisogno di progresso, si potrebbe desiderare di avere uno scheduler che può essere interrogato dal ID compito di ottenere il progresso, piuttosto che un oggetto compito si tiene un riferimento a - avere un oggetto compito che cambia stato contemporaneamente rende difficile ottenere un insieme coerente dei dati di stato da esso, fino a raggiungere uno stato finale. Se lo stato 'passato' non dispone di informazioni fallimento, quindi l'interrogazione 'sono non siete riusciti', seguito da 'ottenere stato di errore' facilmente conduce ad una gara a meno che non esternalizzare bloccaggio (ewww), così restituendo l'oggetto di un'informazione di stato compito immutabile diviene atomicamente desiderabile, quando ormai l'oggetto compito diventa più o meno equivalente al ID passato a una pianificazione.

Questo suona come un'applicazione ideale dell'oggetto ereditarietà e polimorfismo.

abstract class Task
{
      public int TaskId { get; private set; }
      abstract PassedTask TransitionToPassed();
      ...
}

class PendingTask : Task
{
      PassedTask TransitionToPassed()
      {
            PassedTask passed = new PassedTask();
            passed.TaskId = TaskId;
            ...
            return passed;
      }
      ...
}

class PassedTask : Task
{
      PassedTask TransitionToPassed()
      {
            return this;
      }
      ...
}

class FailedTask : Task
{
      public string ReasonForFailure { get; private set; }
      PassedTask TransitionToPassed()
      {
            ...
      }
      ...

}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top