2011-10-10 1 views
5

상태 변수가 있고 해당 클래스에 액세스해야하고 비동기 적으로 작동하는 두 개의 멤버 클래스가있는 클래스가있는 경우. 이것을 구현하는 가장 좋은 방법은 무엇입니까?클래스와 해당 멤버 간의 변수 공유

이 클래스는 비동기 적으로 작동 할

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 
} 

예. DeliveryMan 및 Supplier 클래스 모두 상태를 읽고 쓸 수 있어야합니다. DeliveryMan은 레스토랑의 상태를 푸시하고 공급 업체는 공급 업체의 상태를 수신합니다.

최소 Coupling으로이를 구현하는 더 좋은 방법은 DeliveryMan 또는 Supplier에게 owner Restaurant에 대한 참조를 제공하지 않는 것입니다.

+0

ResturantState가 비공개로 선언되었으므로 다른 클래스가이를 업데이트 할 것으로 예상합니까? – user957902

+0

감사합니다. 액세스 수정자를 내부 – eddiehobbes

+0

으로 변경했습니다. 실제 상태 인 경우 내 (편집 된) 답변과 같은 2 개의 bool로 클래스를 만들 것을 권합니다. – Davy8

답변

1

아마도 상태를 업데이트해야 할 때 실행되는 DeliveryManSupplier 클래스에서 이벤트를 만들 수 있습니다. 식당은 이벤트 핸들러가 호출 될 때 해당 이벤트를 구독하고 이에 따라 자체 상태를 업데이트 할 수 있습니다.

+0

회원 클래스에 상태를 가져 오거나 설정하기위한 델리게이트를주는 것을 생각했습니다. 나는 당신의 대답에 감사하고 그것에 대해 생각합니다. – eddiehobbes

2

그럼 두 개의 내부 클래스에 대한 생성자 매개 변수로 상태를 전달하고 참조 유형으로 간주하여 수정할 수도 있습니다.

+0

답변에 대해 자세히 설명해 주시겠습니까? 상태가 계속 변경되고 deliveryMan이 항상 현재 상태를 제공해야한다고 말하십시오. – eddiehobbes

0

나는 레스토랑 클래스에서 상태를 가져 와서 나머지 클래스의 싱글 톤 또는 팩토리 인 StateManager 클래스를 만듭니다. 귀하의 OO 디자인 이후로 더 많은 답변을 드리기가 어렵습니다.

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

다른 클래스에서 필요한 정보가 들어있는 Order 클래스를 만듭니다. 또한 타이머 이벤트를 확인하는 대기열을 사용하십시오. Order를 dequeue 할 때 Order.State (예를 들어)를보십시오. Enqueue 및 Dequeue 메서드를 사용하여 공용 정적 클래스에 큐를 배치합니다.

DeliveryMan 타이머 이벤트가 발생하면 주문을 큐에서 빼냅니다.

모든 것이 비동기이므로 ConcurrentQueue를 체크 아웃 할 수 있습니다. 공급자는 알림을 기다리기 때문에 IObserver/IObservable을 사용하여 일련 번호가 지정된 Order 개체를 사용하여 공급자에게 스트림 메시지를 보낼 수 있습니다.

도움이 될만한 몇 가지 생각.

1

RestaurantState이 상태 자체가 아닌 상태를 보유하고있는 객체로 만들 수있는 경우 @ Davide의 대답으로 수행하여 생성자에 전달할 수 있습니다.

그러나 enum과 같은 값 유형 인 경우 event 가야 할 길입니다.

DeliveryMan은 새 상태로 이벤트를 발생 시키며, Restaurant은 수신하여 내부 상태를 업데이트합니다.

그러면 상태가 변경 될 때 에서 StateChanged 방법 또는 유사한 것을 호출 할 수 있습니다. 또는 SupplierRestaurantStateEventArgs 또는 Restaurant이 청취 할 수있는 특수 문자와 함께 event을 발생시키고 이벤트 args를 상태로 채울 수 있습니다.

유스 케이스에 따라 다르지만, 단단히 결합 된 경우에도 Restaurant에 대한 참조 만있는 것은 끔찍하지 않을 수 있습니다.

편집 : 당신이 이미 연결되어 RestaurantState보다 "상태"의보다 일반적인 유형이하지 않는, 그래서 사실 경우 DeliveryManSupplier는, 그들은 이미 어느 레스토랑에 연결되어 RestaurantState에 액세스해야합니다.

는 때때로 다시 걸음을하고

A) 디커플링은 당신이 실제로 충분히 분리되어하고있는 것이 도움이 될 수 있는지 여부) 특정 시나리오
B에 실제로 도움이 있는지 확인하는 것이 좋다.

이 경우에도 DeliveryManSupplier을 가구점에 다시 사용할 수 없습니다. (!) 참고로

: 그들은 모두 상호 배타적이지있어 이후

OPEN, 
CLOSED, 
LOW_ON_SUPPLIES 

이 최선의 선택은, 열거 정말 없습니다. 이 클래스가 그렇게한다면 더 나은 될 수있다 :이 경우

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

DeliveryManSupplier 작품의 생성자에 RestaurantState를 전달하는 다비드의 대답 @.

+0

감사합니다. 예를 들어 보겠습니다. 내가 Restaurant State 클래스를 만들고이를 생성자를 통해 전달하면 butcherShop.parentState를 읽음으로써 restaurant.state의 모든 변경 사항이 반영됩니까? – eddiehobbes

+0

@eddiehobbes RestaurantState를 실제 상태 정보를 보유하는 클래스로 만들면 할 수 있지만'butcherShop.RestaurantState.RealState'와 같은 작업을 수행해야합니다. 하나의 속성이있는 경우 조금 복잡하지만'IsOpen','CurrentlyServing' (예 : 아침, 점심, 저녁) 등 여러 유형의 상태가있는 경우 멋지게 작동합니다. – Davy8

+0

@eddiehobbes 이 특정 시나리오에서 디커플링은 실제로 어떤 이점도 제공합니다. 클래스를 '레스토랑'이외의 다른 클래스와 함께 사용할 수 없다면 클래스는 코드를 통하지 않고 단지 암시 적으로 결합되어 있습니다. RestaurantState는 레스토랑 외에는 아무 의미가 없습니다. – Davy8