Sharing a variable between a class and its member
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 event
s 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.
精彩评论