2011-10-10 9 views
5

Se si dispone di una classe che contiene una variabile di stato e due classi membro che devono accedervi e operare in modo asincrono. Qual è il modo migliore per implementarlo?Condivisione di una variabile tra una classe e il suo membro

Un esempio

public enum RestaurantState 
{ 
    BREAKFAST, 
    LUNCH, 
    DINNER 
} 

public class Restaurant 
{ 
    //Below need access to state 
    private DeliveryMan pizzaDriver ; 
    private Supplier butcherShop ; 

    internal RestaurantState state ; 
} 

public DeliveryMan 
{ 
    //Uses a System.Timers.Timer 
    //Wakes up and does work every a minute 
    //Needs to inform state of restaurant 
} 

public Supplier 
{ 
    //Waits and listens for requests to accept deliveries 
    //If suppliers run out we need to change the restaurant state based on our own current state 
} 

Queste classi operano in modo asincrono. Le classi DeliveryMan e Supplier devono essere in grado di leggere/scrivere lo stato. DeliveryMan estrae lo stato del ristorante e il fornitore ascolta lo stato del fornitore.

C'è un modo migliore per progettare questo o un modo per implementarlo con un accoppiamento minimo senza dare a DeliveryMan o al fornitore un riferimento al suo proprietario.

+0

dal momento che ResturantState è dichiarato privato come si prevede che le altre classi lo aggiornino? – user957902

+0

Grazie, ho modificato il modificatore di accesso in interno – eddiehobbes

+0

Se questi sono i tuoi stati attuali, ti consiglio di renderlo un corso con 2 bool come nella mia risposta (modificata). – Davy8

risposta

1

Forse è possibile creare eventi nelle classi DeliveryMan e Supplier che vengono attivate quando è necessario aggiornare lo stato. Il ristorante può iscriversi a questi eventi e aggiornare di conseguenza il proprio stato quando viene richiamato il gestore di eventi.

+0

Ho pensato di dare alle classi membro un delegato per ottenere/impostare lo stato. Apprezzo la tua risposta e ci penso. – eddiehobbes

2

Bene, vorrei passare lo stato come parametro costruttore alle tue due classi interne e, considerato che si tratta di un tipo di riferimento, è possibile modificarlo.

+0

Potresti elaborare la tua risposta? Dire che lo stato cambia continuamente e deliveryMan ha bisogno di dare sempre lo stato attuale – eddiehobbes

0

Prenderei lo stato fuori dalla classe del ristorante e creare una classe StateManager che fosse un singleton o una factory per il resto delle altre classi. È difficile dare una risposta più completa dal momento che il tuo design OO non dà molto da fare.

var restaurant = new Restaurant(); 
var supplier = new Supplier(); 
StateManager.GetState(restaurant); 
StateManager.GetState(supplier); 
0

vorrei creare una classe Order che contiene le informazioni necessarie in un'altra classe. Utilizza anche una coda che controlli su un evento Timer. Quando si abbandona un ordine, consultare Order.State (ad esempio). Metti la coda in una classe statica pubblica con i metodi Enqueue e Dequeue.

Quando scatta l'evento del timer DeliveryMan, deselezionare l'ordine.

Si dice che tutto è asincrono, quindi è possibile controllare ConcurrentQueue. Poiché il Fornitore è in attesa di notifica, è possibile utilizzare IObserver/IObservable per inviare un messaggio di flusso al Fornitore con un oggetto Ordine serializzato ...

Solo alcuni pensieri che potrebbero aiutare.

1

Se RestaurantState è o può essere trasformato in un oggetto che contiene lo stato anziché lo stato stesso, è possibile eseguire la risposta di @ Davide e inoltrarla al costruttore.

Tuttavia, se si tratta di un tipo di valore come un enum poi penso event s sono la strada da percorrere.

DeliveryMan genera un evento con il nuovo stato, che Restaurant ascolta e aggiorna il suo stato interno.

Restaurant può quindi chiamare un metodo StateChanged o qualcosa di simile su Supplier quando lo stato cambia. O Supplier può aumentare un event con uno speciale RestaurantStateEventArgs o qualcosa che lo Restaurant può ascoltare e popolare gli argomenti dell'evento con lo stato.

A seconda del caso d'uso, tuttavia, potrebbe non essere terribile avere un riferimento a Restaurant anche se diventa strettamente accoppiato.

Edit: In realtà se DeliveryMan e Supplier bisogno di accedere a RestaurantState allora sono già un po 'legati a ristoranti, quindi a meno che non si dispone di un tipo più generico di "stato" di RestaurantState sono già accoppiati.

A volte è bene fare un passo indietro e vedere se

a) disaccoppiamento è in realtà utile in uno scenario particolare e
b) se quello che stai facendo è in realtà disaccoppiato abbastanza per essere utile.

In questo scenario, non è ancora possibile riutilizzare DeliveryMan e Supplier per dire un negozio di mobili.

Come sidenote:

OPEN, 
CLOSED, 
LOW_ON_SUPPLIES 

Questi non sono in realtà le scelte migliori per un enum, dal momento che non sono tutti escludono a vicenda. può essere meglio se si trattasse di una classe così:

public class RestaurantState 
{ 
    public bool IsOpen { get; set; } 
    public bool IsLowOnSupplies { get; set; } 
} 

In tal caso, @ risposta di Davide per il passaggio RestaurantState al costruttore di DeliveryMan e Supplier funziona bene.

+0

Grazie, cercherò di migliorare l'esempio. Se faccio diventare Restaurant State una classe e la passo attraverso il costruttore, leggerò macellaioShop.parentState e rifletterò tutte le modifiche in restaurant.state? – eddiehobbes

+0

@eddiehobbes se fai RestaurantState una classe che contiene le informazioni sullo stato reale, allora puoi farlo, ma dovrai fare qualcosa come 'butcherShop.RestaurantState.RealState'. È un po 'goffo se c'è una proprietà, ma funziona bene se si hanno più tipi di stato, come 'IsOpen'' AttualmenteServing' (ad es. Colazione, Pranzo, Cena), ecc. – Davy8

+0

@eddiehobbes Vorrei ancora valutare se disaccoppiare in questo particolare scenario ti dà effettivamente dei benefici. Se non puoi usare le classi con qualcosa di diverso da "Restaurant", allora sono già implicitamente accoppiati, non attraverso il codice, ma solo in base alla progettazione, ad es. RestaurantState non ha senso per qualcosa di diverso dai ristoranti. – Davy8

Problemi correlati