2011-10-10 15 views
5

Jeśli masz klasę zawierającą zmienną stanu i dwie klasy elementów, które potrzebują do niej dostępu i działają asynchronicznie. Jaki jest najlepszy sposób wdrożenia tego?Udostępnianie zmiennej między klasą a jej członkiem

Przykładem

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 
} 

Klasy te działają asynchronicznie. Zarówno klasa DeliveryMan, jak i Supplier muszą mieć możliwość odczytu/zapisu stanu. DeliveryMan wypiera stan restauracji i Dostawca nasłuchuje statusu dostawcy.

Czy istnieje lepszy sposób zaprojektowania tego lub sposób wdrożenia go przy minimalnym sprzężeniu bez podawania dostawcy lub dostawcy odniesienia do jego restauracji właściciela.

+0

od czasu, gdy ResturantState jest zadeklarowane jako prywatne, ponieważ można oczekiwać, że inne klasy zaktualizują go? – user957902

+0

Dzięki, zmieniłem modyfikator dostępu na wewnętrzny – eddiehobbes

+0

Jeśli są to twoje rzeczywiste stany, poleciłbym uczynić go klasą z 2 taktami jak w mojej (edytowanej) odpowiedzi. – Davy8

Odpowiedz

1

Być może można tworzyć zdarzenia na klasach DeliveryMan i Supplier, które są uruchamiane, gdy stan wymaga aktualizacji. Restauracja może zapisać się do tych wydarzeń i odpowiednio zaktualizować swój stan, gdy wywoływacz zdarzeń zostanie wywołany.

+0

Pomyślałem o nadaniu klasie członka delegata, aby uzyskać/ustawić stan. Doceniam twoją odpowiedź i myślenie na jej temat. – eddiehobbes

2

Cóż, przekazałbym stan jako parametr konstruktora do twoich dwóch klas wewnętrznych i biorąc pod uwagę, że jest to typ odniesienia, można go również zmodyfikować.

+0

Czy mógłbyś rozwinąć swoją odpowiedź? Powiedzmy, że stan nieustannie się zmienia, a deliveryMan musi zawsze podawać aktualny stan. – eddiehobbes

0

Wezmę stan z klasy restauracji i utworzę klasę StateManager, która jest singletonem lub fabryką dla pozostałych klas. Trudno podać bardziej kompletną odpowiedź, ponieważ twój projekt OO nie daje wiele do kontynuowania.

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

Utworzę klasę Order, która zawiera informacje potrzebne w innej klasie. Użyj także kolejki, którą sprawdzasz w zdarzeniu czasomierza. Kiedy anulujesz zamówienie, spójrz na Order.State (na przykład). Umieść kolejkę w publicznej klasie statycznej za pomocą metod Enqueue and Dequeue.

Po uruchomieniu zdarzenia licznika DeliveryMan, wycofanie zamówienia.

Wspominasz, że wszystko jest asynchroniczne, możesz więc sprawdzić ConcurrentQueue. Ponieważ Dostawca czeka na powiadomienie, możesz użyć IObserver/IObservable, aby wysłać wiadomość strumieniową do Dostawcy z serializowanym obiektem zamówienia ...

Pomysły, które mogą pomóc.

1

Jeśli obiekt jest lub może zostać przekształcony w obiekt, który przechowuje stan, a nie sam stan, wówczas można wykonać odpowiedź @ Davide i przekazać ją do konstruktora.

Jednak jeśli jest to typ wartości, taki jak enum, to myślę, że są to drogi, do których należy się zmierzyć: .

DeliveryMan podnosi wydarzenie o nowym stanie, które Restaurant słucha i aktualizuje jego stan wewnętrzny.

Restaurant można wtedy wywołać metodę StateChanged lub coś podobnego na Supplier, gdy stan się zmieni. Lub Supplier może podnieść event ze specjalnym RestaurantStateEventArgs lub czymś, co Restaurant może nasłuchiwać i zapełniać zdarzenia ze stanem.

W zależności od przypadku użycia, może nie być straszne, aby po prostu mieć odniesienie do Restaurant, mimo że jest ściśle sprzężony.

Edit: Właściwie jeśli DeliveryMan i Supplier potrzebują dostępu do RestaurantState następnie są one już nieco przywiązany do restauracji, więc jeśli masz więcej rodzajowe typu „państwo” niż RestaurantState są już sprzężone.

Czasami dobrze jest zrobić krok wstecz i zobaczyć, czy

a) oddzielenie jest rzeczywiście pomocne w konkretnym scenariuszu i
b) czy to co robisz jest rzeczywiście oddzielone wystarczy być użyteczne.

W tym scenariuszu nadal nie można ponownie użyć DeliveryMan i Supplier na przykład sklepu meblowego.

Jak sidenote:

OPEN, 
CLOSED, 
LOW_ON_SUPPLIES 

one naprawdę nie są najlepszym wyborem dla wyliczenia, gdyż nie wszyscy wzajemnie się wykluczają. Może byłoby lepiej, gdyby to była klasa tak:

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

W takim przypadku @ odpowiedź Davide za przepuszczanie RestaurantState do konstruktora DeliveryMan i Supplier działa dobrze.

+0

Dzięki, spróbuję poprawić ten przykład. Jeśli sprawię, że restauracja stanie się klasą i przekażę ją przez konstruktora, będzie czytać butcherShop.parentState odzwierciedlać wszystkie zmiany w restaurant.state? – eddiehobbes

+0

@eddiehobbes, jeśli uczynisz z RestaurantState klasę zawierającą prawdziwe informacje o stanie, wtedy możesz, ale będziesz musiał zrobić coś w stylu 'ButcherShop.RestaurantState.RealState'. Jest trochę niezgrabny, jeśli istnieje jedna właściwość, ale działa dobrze, jeśli masz wiele typów stanów, takich jak 'IsOpen'' CurrentServing' (np. Śniadanie, lunch, kolacja), itp. – Davy8

+0

@eddiehobbes Wciąż zastanawiałbym się czy oddzielenie w tym konkretnym scenariuszu faktycznie daje jakiekolwiek korzyści. Jeśli nie możesz używać klas z czymkolwiek innym niż "Restauracja", to są one już pośrednio sprzężone, nie przez kod, ale tylko przez projekt, np. RestaurantState nie ma sensu dla niczego innego niż Restauracje. – Davy8

Powiązane problemy