2011-10-10 1 views
5

Si vous avez une classe qui contient une variable d'état et deux classes de membres qui doivent y accéder et fonctionner de manière asynchrone. Quelle est la meilleure façon de mettre en œuvre cela?Partage d'une variable entre une classe et son membre

Un exemple

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 
} 

Ces classes fonctionnent de manière asynchrone. Les deux classes DeliveryMan et Supplier doivent pouvoir lire/écrire l'état. DeliveryMan pousse l'état du restaurant et le fournisseur est à l'écoute du statut de son fournisseur.

Y a-t-il une meilleure façon de concevoir ceci ou une façon de l'implémenter avec un couplage minimal sans donner à DeliveryMan ou à un fournisseur une référence à son propriétaire Restaurant.

+0

depuis ResturantState est déclaré comme privé comment vous vous attendez à ce que les autres classes le mettent à jour? – user957902

+0

Merci, j'ai changé le modificateur d'accès en interne – eddiehobbes

+0

Si ce sont vos états actuels, je vous recommande de faire une classe avec 2 booléens comme dans ma réponse (éditée). – Davy8

Répondre

1

Vous pouvez peut-être créer des événements sur les classes DeliveryMan et Supplier qui sont déclenchées lorsque l'état doit être mis à jour. Le restaurant peut s'abonner à ces événements et mettre à jour son propre état en conséquence lorsque le (s) gestionnaire (s) d'événement est appelé (s).

+0

Je pensais donner un délégué aux classes membres pour obtenir/définir l'état. J'apprécie votre réponse et y réfléchis. – eddiehobbes

2

Eh bien, je passerais l'état en tant que paramètre constructeur à vos deux classes internes et en considérant qu'il s'agit d'un type de référence, il peut également être modifié.

+0

Pourriez-vous élaborer sur votre réponse? Dites l'état change continuellement et deliveryMan doit toujours donner l'état actuel – eddiehobbes

0

Je voudrais sortir l'état de la classe de restaurant et faire une classe StateManager qui était un singleton ou une usine pour le reste des autres classes. Il est difficile de donner une réponse plus complète puisque votre conception OO ne donne pas beaucoup à continuer.

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

Je voudrais créer une classe Order qui contient les informations dont vous avez besoin dans une autre classe. Utilisez également une file d'attente que vous vérifiez sur un événement Timer. Lorsque vous supprimez une commande, regardez Order.State (par exemple). Placez la file d'attente dans une classe statique publique avec les méthodes Enqueue et Dequeue.

Lorsque l'événement du temporisateur DeliveryMan se déclenche, réinitialisez l'ordre.

Vous mentionnez que tout est asynchrone, donc vous pouvez vérifier ConcurrentQueue. Étant donné que le fournisseur attend une notification, vous pouvez utiliser IObserver/IObservable pour envoyer un message de flux au fournisseur avec un objet de commande sérialisé ...

Juste quelques réflexions qui pourraient aider.

1

Si RestaurantState est ou peut être transformé en un objet qui contient l'état plutôt que l'état lui-même, alors vous pouvez faire comme réponse @ Davide et le transmettre au constructeur.

Toutefois, si c'est un type de valeur comme un enum alors je pense que event s sont la voie à suivre.

DeliveryMan déclenche un événement avec le nouvel état, que Restaurant écoute et met à jour son état interne.

Restaurant peut ensuite appeler une méthode StateChanged ou quelque chose de similaire sur Supplier lorsque l'état change. Ou Supplier peut lever un event avec un RestaurantStateEventArgs spécial ou quelque chose que le Restaurant peut écouter et remplir les arguments d'événement avec l'état.Cependant, selon le cas d'utilisation, il n'est peut-être pas terrible d'avoir simplement une référence à Restaurant même si elle est fortement couplée.

Modifier: En fait, si DeliveryMan et Supplier besoin d'accéder à RestaurantState alors ils sont déjà un peu liés à des restaurants, sauf si vous avez un type plus générique de « état » que RestaurantState ils sont déjà couplés.

Parfois, il est bon de faire un pas en arrière et voir si

a) le découplage est en fait utile dans un scénario particulier et
b) si ce que vous faites est en fait assez découplé pour être utile.

Dans ce scénario, vous ne pouviez toujours pas réutiliser DeliveryMan et Supplier pour, par exemple, un magasin de meubles.

En sidenote:

OPEN, 
CLOSED, 
LOW_ON_SUPPLIES 

Ce ne sont pas vraiment les meilleurs choix pour un ENUM, car ils ne sont pas mutuellement exclusifs. il peut être préférable si elle était une classe si:

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

Dans ce cas, la réponse de @ Davide pour passer RestaurantState dans le constructeur de DeliveryMan et Supplier fonctionne bien.

+0

Merci, je vais essayer d'améliorer l'exemple. Si je fais une classe Restaurant State et que je la passe par le constructeur, est-ce que la lecture de butcherShop.parentState reflètera tous les changements dans restaurant.state? – eddiehobbes

+0

@eddiehobbes Si vous faites de RestaurantState une classe qui contient les informations sur l'état réel, alors vous pouvez, mais vous devrez faire quelque chose comme 'butcherShop.RestaurantState.RealState'. C'est un peu maladroit s'il y a une seule propriété, mais cela fonctionne bien si vous avez plusieurs types d'état, comme 'IsOpen'' CurrentlyServing' (par ex. Petit déjeuner, Déjeuner, Dîner), etc. – Davy8

+0

@eddiehobbes Je considérerais encore si découplage dans ce scénario particulier vous donne effectivement des avantages. Si vous ne pouvez pas utiliser les classes avec autre chose que 'Restaurant', elles sont déjà implicitement couplées, pas par le biais du code, mais simplement par la conception, par ex. RestaurantState n'a pas de sens pour autre chose que des restaurants. – Davy8

Questions connexes