2011-10-10 15 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 
} 

इन कक्षाओं एसिंक्रोनस रूप से कार्य करते हैं। डिलिवरीमेन और प्रदायक वर्ग दोनों को राज्य को पढ़ने/लिखने में सक्षम होना चाहिए। डिलिवरीमैन रेस्तरां की स्थिति को धक्का देता है और प्रदायक अपनी सप्लायर की स्थिति के लिए सुनता है।

क्या डिलिवरीमैन या प्रदायक को अपने मालिक रेस्तरां के संदर्भ में दिए बिना न्यूनतम युग्मन के साथ इसे कार्यान्वित करने का एक बेहतर तरीका है।

+0

चूंकि ResturantState को निजी के रूप में घोषित किया जाता है कि आप अन्य वर्गों को इसे अपडेट करने की अपेक्षा कैसे करते हैं? – user957902

+0

धन्यवाद, मैंने आंतरिक – eddiehobbes

+0

में एक्सेस संशोधक को बदल दिया है, यदि वे आपके वास्तविक राज्य हैं, तो मैं इसे अपने (संपादित) उत्तर में 2 बूल के साथ कक्षा बनाने की अनुशंसा करता हूं। – Davy8

उत्तर

1

शायद आप DeliveryMan और Supplier कक्षाओं पर ईवेंट बना सकते हैं जिन्हें राज्य को अद्यतन करने की आवश्यकता होने पर निकाल दिया जाता है। रेस्तरां इन घटनाओं की सदस्यता ले सकता है और जब ईवेंट हैंडलर का आह्वान किया जाता है तो तदनुसार अपने राज्य को अपडेट कर सकते हैं।

+0

मैंने सदस्य वर्ग को राज्य प्राप्त करने/सेट करने के लिए एक प्रतिनिधि को देने का विचार किया। मैं आपके उत्तर और इस पर विचार की सराहना करता हूं। – eddiehobbes

2

वैसे मैं राज्य को आपके दो आंतरिक वर्गों में कन्स्ट्रक्टर पैरामीटर के रूप में पास कर दूंगा और यह मानता हूं कि यह एक संदर्भ प्रकार है जिसे इसे भी संशोधित किया जा सकता है।

+0

क्या आप अपने उत्तर पर विस्तार कर सकते हैं? राज्य को लगातार परिवर्तन और वितरण कहें, हमेशा मौजूदा स्थिति – eddiehobbes

0

मैं राज्य को रेस्तरां कक्षा से बाहर ले जाऊंगा और StateManager कक्षा बनाउंगा जो अन्य सिंगल वर्गों के लिए सिंगलटन या कारखाना था। आपके ओओ डिज़ाइन पर जाने के लिए बहुत कुछ देने के बाद से अधिक पूर्ण जवाब देना मुश्किल है।

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

मैं एक Order वर्ग है कि जानकारी यदि आप किसी अन्य वर्ग में आवश्यकता होती है पैदा करेगा। एक कतार का भी उपयोग करें जिसे आप टाइमर ईवेंट पर चेक करते हैं। जब आप ऑर्डर देते हैं, तो ऑर्डर.स्टेट देखें (उदाहरण के लिए)। क्यूई को एक सार्वजनिक स्थैतिक वर्ग में एनक्यू और डेक्यू विधियों के साथ रखें।

जब डिलिवरीमैन टाइमर घटना आग लगती है, ऑर्डर को हटा दें।

आप उल्लेख करते हैं कि सबकुछ एसिंक है, इसलिए आप ConcurrentQueue देख सकते हैं। चूंकि प्रदायक अधिसूचना के लिए इंतजार कर रहा है, इसलिए आप एक क्रमबद्ध ऑर्डर ऑब्जेक्ट के साथ प्रदायक को स्ट्रीम संदेश भेजने के लिए IObserver/IObservable का उपयोग कर सकते हैं ...

बस कुछ विचार जो मदद कर सकते हैं।

1

यदि RestaurantState किसी ऑब्जेक्ट में बनाया गया है या राज्य के बजाय राज्य को रखता है, तो आप @ डेविड के जवाब के रूप में कर सकते हैं और इसे कन्स्ट्रक्टर में भेज सकते हैं।

हालांकि यदि यह enum जैसा मान प्रकार है तो मुझे लगता है कि event एस जाने का तरीका है।

DeliveryMan नए राज्य के साथ एक कार्यक्रम उठाता है, Restaurant इसकी आंतरिक स्थिति को सुनता है और अपडेट करता है।

Restaurant तब StateChanged विधि या Supplier पर कुछ ऐसा ही कह सकता है जब राज्य बदलता है। या Supplierevent को विशेष RestaurantStateEventArgs या के साथ राज्य के साथ ईवेंट तर्कों को सुन और पॉप्युलेट कर सकता है।

हालांकि, केस-केस के आधार पर, का संदर्भ होने के बावजूद यह भयानक नहीं हो सकता है, भले ही यह कसकर मिल जाए।

संपादित: असल में अगर DeliveryMan और SupplierRestaurantState तो वे पहले से ही कुछ हद तक रेस्टोरेंट्स से जुड़े होते हैं के लिए उपयोग की जरूरत है, तो जब तक आप "राज्य" RestaurantState की तुलना में वे पहले से ही मिलकर कर रहे हैं की एक अधिक सामान्य प्रकार है।

कभी कभी यह एक कदम पीछे जाएं और अगर

क) decoupling वास्तव में एक विशेष परिदृश्य और
ख में सहायक) क्या तुम क्या कर रहे हैं वास्तव में काफी decoupled है उपयोगी होने के लिए है देखने के लिए अच्छा है।

इस परिदृश्य में, आप अभी भी फर्नीचर स्टोर कहने के लिए DeliveryMan और Supplier का पुन: उपयोग नहीं कर सके।

एक sidenote के रूप:

OPEN, 
CLOSED, 
LOW_ON_SUPPLIES 

ये नहीं वास्तव में सबसे अच्छा विकल्प एक enum के लिए है, क्योंकि वे सब परस्पर अनन्य नहीं कर रहे हैं। यह बेहतर हो सकता है अगर यह एक वर्ग तो थे:

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

उस मामले में, @ अच्छी तरह से DeliveryMan और Supplier कार्यों के निर्माता में RestaurantState पारित करने के लिए डेविड का जवाब।

+0

धन्यवाद देने की आवश्यकता है, धन्यवाद, मैं उदाहरण का प्रयास और सुधार करूंगा। अगर मैं रेस्तरां राज्य को एक वर्ग बनाता हूं और मैं इसे कन्स्ट्रक्टर के माध्यम से पास करता हूं, तो butcherShop.parentState पढ़ना होगा रेस्तरां में किसी भी और सभी बदलावों को दर्शाता है। – eddiehobbes

+0

@eddiehobbes यदि आप रेस्तरांस्टेट को एक ऐसी कक्षा बनाते हैं जो वास्तविक स्थिति की जानकारी रखती है, तो आप कर सकते हैं, लेकिन आपको 'butcherShop.RestaurantState.RealState' करना होगा। यदि कोई एक संपत्ति है तो यह थोड़ा सा गुंजाइश है, लेकिन यदि आपके पास कई प्रकार के राज्य हैं, जैसे 'IsOpen'' वर्तमान सेवा '(जैसे नाश्ता, दोपहर का भोजन, रात्रिभोज), आदि – Davy8

+0

@eddiehobbes मैं अभी भी इस बात पर विचार करता हूं कि यह अभी भी काम करेगा या नहीं इस विशेष परिदृश्य में decoupling वास्तव में आपको कोई लाभ देता है। यदि आप 'रेस्तरां' के अलावा किसी अन्य चीज़ के साथ कक्षाओं का उपयोग नहीं कर सकते हैं, तो वे कोड के माध्यम से नहीं, बल्कि डिजाइन द्वारा, उदाहरण के लिए पहले ही पूरी तरह से युग्मित हैं। रेस्टोरेंटस्टेट रेस्तरां के अलावा किसी अन्य चीज़ के लिए समझ में नहीं आता है। – Davy8

संबंधित मुद्दे