2011-06-23 11 views
6

मेरे पास एक सार "एक्शन" क्लास है, जिसने एक्शन एपॉइंटमेंट, एक्शनकॉल, एक्शनईमेल और एक्शनलेटर के प्रकार प्राप्त किए हैं। मैं एक ऐसा फ़ंक्शन लिखने की कोशिश कर रहा हूं जो हमारी सेवा परत को ड्रॉ करेगा, इसलिए हम अब 5 बार सीआरयूडी कॉल नहीं लिख रहे हैं। । (यानी मैंसी # अमूर्त वर्ग विशिष्ट कोड के लिए पैटर्न

private IServiceResponse UpdateAction<T>(T action, string originalActionStatus) where T : Action 
{ 
     if (action.GetType() == typeof(Action)) 
     { 
      _actionRepository.Update(action); 
     } 
     else if (action.GetType() == typeof(ActionAppointment)) 
     { 
      _actionAppointmentRepository.Update(action as ActionAppointment); 
     } 
     else if (action.GetType() == typeof(ActionCall)) 
     { 
      _actionCallRepository.Update(action as ActionCall); 
     } 
     else if (action.GetType() == typeof(ActionEmail)) 
     { 
      _actionEmailRepository.Update(action as ActionEmail); 
     } 
     else if (action.GetType() == typeof(ActionLetter)) 
     { 
      _actionLetterRepository.Update(action as ActionLetter); 
     } 
} 

दुर्भाग्य से, कैसे हमारे खजाने सेटअप कर रहे हैं, मैं विशेष रूप से नामित खजाने का उपयोग करना होगा:

मैं कुछ अपडेट तर्क (संक्षिप्तता के लिए हटाया अन्य कोड के बहुत सारे) हमारी सेवा परत में है _actionRepository के माध्यम से एक्शनलेटर को अपडेट नहीं किया जा सकता है, भले ही यह क्रिया से प्राप्त हो)

मैं विभिन्न पैटर्न पर पढ़ रहा हूं, और यह फैक्टरी पैटर्न के समान कुछ लगता है, लेकिन मैं इसे कैसे काम नहीं कर सकता।

क्या मुझे कुछ बेवकूफ याद आ रही है?

+1

आप * विज़िटर * पैटर्न (http://en.wikipedia.org/wiki/Visitor_pattern) पर विचार कर सकते हैं। –

+2

हां एक कारखाना पैटर्न एक समाधान है। आपके रेपॉजिटरीज़ में या तो एक सामान्य आधार वर्ग होना चाहिए या एक इंटरफ़ेस लागू करना चाहिए। उनके पास एक अद्यतन विधि होनी चाहिए जो क्रिया के रूप में टाइप की गई वस्तु को स्वीकार करे। फैक्ट्री इस प्रकार को पैरामीटर के रूप में स्वीकार करती है (जो भी फॉर्म, नाम, प्रकार, enum में उपलब्ध है) और सही भंडार देता है। बिल्कुल यही बात है। कारखाने को कार्यान्वित करने के तरीके पर भ्रम का एक विशिष्ट बिंदु है? – Sisyphus

+0

मुझे इस बात के बारे में अनिश्चितता है कि इस के लिए कारखाने के पैटर्न को कैसे कार्यान्वित किया जाए, क्योंकि प्रत्येक डोमेन मॉडल ऑब्जेक्ट पर आधारित आईरिपॉजिटरी सामान्य है। धीमी प्रतिक्रिया के लिए – mandreko

उत्तर

11

क्या आप प्रत्येक क्रिया प्रकार के लिए उस विधि का अधिभार नहीं लिख सकते हैं? <T> और typeof सामान भूल जाएं - आप जो कर रहे हैं वह एक अंतर्निहित भाषा सुविधा (विधि अधिभार) को हाथ से और एक नाजुक तरीके से भी कार्यान्वित कर रहा है।

+3

हां, यह बिल्कुल सही है कि बहुरूपता और विरासत क्या है। –

+0

कोड पहले प्रत्येक एक्शन प्रकार के लिए एक विधि के रूप में लिखा गया था। मैं बस कुछ इसे ड्रॉ करने की कोशिश कर रहा हूं, लेकिन मुझे लगता है कि मैं कुछ साझा घटकों को ड्रॉ कर सकता हूं, लेकिन प्रत्येक में विशिष्ट भंडार कोड है। – mandreko

+0

@ मैट: आपका अगर अन्यथा कॉन्ट्रैक्शन कोड को कोई भी DRYer नहीं बना रहा है, तो यह निश्चित रूप से है। –

-2

के तर्क यहाँ उलटा करते हैं:

abstract class Action { 
    protected abstract Repository GetRepository(); 
    protected void Update(){ 
     this.GetRepository().Update(this); 
    } 
} 

आपको बस इतना करना है पाने वर्गों में से प्रत्येक में GetRepository ओवरराइड है। उदाहरण के लिए:

class ActionAppointment : Action { 
    protected override Repository GetRepository() { 
     return _actionAppointmentRepository; 
    } 
} 
+1

मॉडल क्लास के लिए यह बहुत अच्छा विचार नहीं है कि यह कैसे संग्रहीत किया जाए। –

+2

-1, डोमेन ऑब्जेक्ट्स में इंजेक्शन सेवाएं (यहां तक ​​कि भंडार) एक बुरी आदत है। – smartcaveman

+0

smartcaveman के साथ सहमत हुए। यह उस प्रकार की निर्भरता रखने के लिए हमारे नियमों का उल्लंघन करता है। – mandreko

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