开发者

Sharing a variable between a class and its member

开发者 https://www.devze.com 2023-04-12 13:54 出处:网络
If you have a class that contains a state variable and two member classes t开发者_如何学Chat need access to it and operate asynchronously. What is the best way to implement this?

If you have a class that contains a state variable and two member classes t开发者_如何学Chat need access to it and operate asynchronously. What is the best way to implement this?

An example

 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
}

These classes operate asynchronously. Both DeliveryMan and Supplier classes need to be able to read/write the state. DeliveryMan pushes out the state of the restaurant and the Supplier listens for its supplier's status.

Is there a better way to design this or a way to implement it with minimal coupling without giving DeliveryMan or Supplier a reference to its owner Restaurant.


Well i would pass the state as constructor parameter to your two inner classes and considering that it is a reference type it can be modified as well.


Perhaps you can create events on the DeliveryMan and Supplier classes that are fired when the state needs to be updated. The Restaurant can subscribe to these events and update its own state accordingly when the event handler(s) are invoked.


If RestaurantState is or can be made into an object that holds the state rather than the state itself, then you can do as @Davide's answer and pass it in to the constructor.

However if it's a value type like an enum then I think events are the way to go.

DeliveryMan raises an event with the new state, that Restaurant listens to and updates it's internal state.

Restaurant can then call a StateChanged method or something similar on Supplier when the state changes. Or Supplier can raise an event with a special RestaurantStateEventArgs or something that the Restaurant can listen to and populate the event args with the state.

Depending on the use-case though, it may not be terrible to just have a reference to Restaurant even though it does become tightly coupled.

Edit: Actually if DeliveryMan and Supplier need access to RestaurantState then they are already somewhat tied to Restaurants, so unless you have a more generic type of "state" than RestaurantState they are already coupled.

Sometimes it's good to take a step back and see if

a) decoupling is actually helpful in a particular scenario and
b) whether what you're doing is actually decoupled enough to be useful.

In this scenario, you still couldn't reuse DeliveryMan and Supplier for say a furniture store.

As a sidenote:

OPEN,
CLOSED,
LOW_ON_SUPPLIES

These aren't really the best choices for an enum, since they're not all mutually exclusive. it may be better if it were a class so:

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

In that case, @Davide's answer for passing RestaurantState into the constructor of DeliveryMan and Supplier works well.


I would take the state out of the restaurant class and make a StateManager class that was a singleton or a factory for the rest of the other classes. Its hard to give a more complete answer since your OO design doesnt give much to go on.

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


I would create an Order class that contains the information you need in another class. Also use a Queue which you check on a Timer event. When you dequeue an Order, look at Order.State (for instance). Put the Queue in a public static class with Enqueue and Dequeue methods.

When the DeliveryMan timer event fires, dequeue the Order.

You mention that everything is async, so you might check out ConcurrentQueue. Since Supplier waits for notification, you can use IObserver/IObservable to send a stream message to Supplier with a serialized Order object ...

Just some thoughts that might help out.

0

精彩评论

暂无评论...
验证码 换一张
取 消