2013-04-01 4 views
5

Non sono abbastanza sicuro di come pronunciare questa domanda in una frase, quindi ho avuto difficoltà a cercare i post precedenti. Questo succede spesso per me e mi piacerebbe avere un consenso su come affrontarlo.Quando controllare lo stato di un oggetto, OOP generale, esempio in C#

Supponiamo di avere due classi, ExampleClass e ExampleClassManager. ExampleClass ha un metodo Update(Data data) che viene chiamato da ExampleClassManager. Tuttavia, ExampleClass può essere in uno dei due stati, e nello stato Enabled si vuole elaborare il data passata ad essa in Update, e nello stato disabilitato non fa nulla con il data a tutti.

Dovrei controllare per lo stato nel ExampleClassManager e non superato il data affatto se è disabilitato, o forse dovrei passare il data indipendentemente e ignorarlo all'interno ExampleClass?

Ecco un esempio di codice nel caso in cui non lo articolassi chiaramente.

public class ExampleClass { 
    public bool Enabled { 
     get; 
     set; 
    } 

    public void Update(Data data) { 
     if(Enabled) { 
      //do stuff with data 
     } 
    } 
} 

public class ExampleClassManager { 
    private List<ExampleClass> exampleClassList=new List<ExampleClass>(); 

    public void UpdateList() { 
     foreach(ExampleClass exampleClass in exampleClassList) { 
      exampleClass.Update(data); 
     } 
    } 
} 

o

public class ExampleClass { 
    public bool Enabled { 
     get; 
     set; 
    } 

    public void Update(Data data) { 
     //do stuff with data 
    } 
} 

public class ExampleClassManager { 
    private List<ExampleClass> exampleClassList=new List<ExampleClass>(); 

    public void UpdateList() { 
     foreach(ExampleClass exampleClass in exampleClassList) { 
      if(exampleClass.Enabled) { 
       exampleClass.Update(data); 
      } 
     } 
    } 
} 
+3

Bene, le domande che vorrei porre sono: A) Cosa succede se "Aggiornato" un 'EsempioClass' disabilitato, quindi abilitato quell'istanza. Dovrebbe mostrare i dati che erano vincolati a _before_ essere disabilitato, o dovrebbe mostrare i dati aggiornati che sono stati forniti quando è stato disabilitato? B) Il 'ExampleClassManager' _care_, indipendentemente dal fatto che' ExampleClass' sia abilitato durante la distribuzione dei suoi dati? C) Ti aspetti di avere altre implementazioni/sottoclassi di 'ExampleClass' dove dovresti desiderare i dati o avere altri concetti" aggiornabili "che dovrebbero cambiare quando" aggiornati "anche se disabilitati? –

+0

Inoltre D) Vuoi chiamare il codice per forzare gli aggiornamenti sulle istanze 'ExampleClass' disabilitate? Nel secondo esempio, il codice chiamante può _ignore_ il fatto che un'istanza è disabilitata e impone modifiche su di essa. Tutto il codice di qualsiasi classe che chiama 'Update' deve quindi soddisfare questo contratto" non aggiornarmi se sono disabilitato ", ma non è obbligato a farlo _. –

+1

Dipende davvero dall'importanza dell'elaborazione dei dati di input. In questo scenario, 'ExampleClass' non ha scelto come gestire lo stato disabilitato, piuttosto fa in modo che i client effettuino tale scelta. Potresti considerare questo cattivo design. Non ti informa che non accadrà nulla con il tuo contributo. Se l'elaborazione dei dati da parte di 'ExampleClass' è importante, è possibile controllare questo stato disabilitato. Tuttavia, come rispondi allo stato disattivo? Lanciare un'eccezione? Ignorare? Prova un'altra via? Registra qualcosa? –

risposta

3

Dato che dipende da una proprietà di ExampleClass, sceglierei l'opzione 1 e assegno entro ExampleClass.Update. In caso contrario, qualsiasi oggetto con accesso a un oggetto ExampleClass potrebbe chiamare Updateindipendentemente dallo dello stato. Controllando all'interno del metodo Update, ci si assicura che procederà solo se l'oggetto è abilitato. La domanda qui è chi può cambiare lo stato dell'oggetto?

Vedere la Law of Demeter:

Ogni unità deve essere a conoscenza solo limitata su altre unità: solo le unità "da vicino" correlate a l'unità corrente.

+0

Grazie, viene visualizzata una domanda correlata. Se ho un numero di ExampleClasses e un ExampleClassManager per gestirli, sarebbe meglio rendere "Enabled" privato e far sì che ogni ExampleClass sia responsabile del proprio stato? O dovrei rendere "Abilitato" una proprietà pubblica e chiedere al gestore di impostare gli stati ExampleClass? Nel mio esempio semplificato, indipendentemente dal fatto che "Abilitato" sia vero/falso dipende da come l'EsempioClass reagisce internamente agli oggetti "Dati" che gli vengono passati. Potrei aver appena risposto alla mia stessa domanda con quell'ultima frase, ma per favore conferma. – tmakino

+0

Se ogni ExampleClass è completamente responsabile del proprio stato, la mia classe manager diventa semplicemente un dizionario glorificato dove int è un ID univoco. Consiglieresti di avere una classe "Manager" complessa con semplici SampleClass o una ExampleClass complessa con un Manager semplice? Esiste una risposta generale accettata o dipende da ciascun caso specifico? – tmakino

+0

Come vedo, sì, hai risposto alla tua stessa domanda :-) Se il solo responsabile delle modifiche di stato è il 'ExampleClass', imposta il setter' private' e il getter 'public'. Dovresti anche considerare il setter come 'internal' se altre classi _con la tua assembly_ potrebbero cambiarlo. –

0

"Quanto deve essere gestita la classe del mio manager?" La tua opzione 2 è l'approccio "micromanagement" - che il Manager dovrebbe dettare ogni piccolo dettaglio alla ExampleClass su cosa dovrebbe fare e come.

In genere, questa è una programmazione più basata sulla struttura rispetto alla programmazione orientata agli oggetti. Mi aspetto che il tuo manager dica al tuo oggetto "vai a fare questo" e non preoccuparti dei dettagli. ExampleClass dovrebbe incapsulare tutto il suo comportamento internamente e non costringere il gestore a preoccuparsi di ciò.

mio voto è per l'opzione 1, con l'avvertenza che si tratta di principi generali, e sarai sempre in grado di trovare qualche caso in cui si desidera l'opzione 2.

Una domanda per chiedere - c'è un motivo che ExampleClass.Enabled.get è pubblico, a parte lasciare che il gestore controlli? Se questo è l'unico motivo per cui è pubblico, allora è un'implementazione interna e il gettor dovrebbe essere privato. Se hai un sacco di cose da guardare in questo campo, ciò potrebbe implicare che il tuo flusso di lavoro opzione 2 è più naturale per questa classe.

0

Sceglierei l'opzione 2, classManager dovrebbe gestire gli oggetti, dovrebbe sapere se attivare o meno l'aggiornamento. Il metodo di aggiornamento del singolo oggetto dovrebbe fare ciò che dice (aggiornare l'oggetto e non fare nulla).

@caerolus: Non posso commentare ancora ... in ogni caso nessuno dei due l'esempio dato ha rotto la legge di Demetra

Comunque penso che questa è una domanda un po 'personale scelta, forse è più adatto per lo scambio di stack?

0

Supponiamo di avere due oggetti, Azienda e Dipendente. Hai l'assegno dell'azienda quando il dipendente ha fame o hai il dipendente che controlla se ha fame? Sembra che tu voglia che il dipendente controlli se ha fame, giusto? Ma cosa succede se l'azienda vuole ordinare cibo per tutti i dipendenti, quindi l'azienda deve verificare se il dipendente ha fame.

Quindi il mio punto è, dipende dal design e dal contesto di quando controllare e chi sta controllando e perché. Nel tuo esempio, direi che non ha importanza perché il contesto non è impostato.

+0

Bel esempio! Ma penso che sia un po 'come questo: l'operazione è 'Eat' (' Aggiorna' qui). Chi decide se mangiare o no? Il dipendente. La società può verificare se un dipendente è 'Affamato' (' Abilitato' qui) o no? Sì, ma alla fine, è la decisione del dipendente di mangiare o no. Quindi puoi far sapere a tutti se hai fame o no, ma solo tu dovresti decidere se mangiare o meno ... e quindi non avere più fame. –

Problemi correlati