2009-05-17 14 views
6

अद्यतन: एक और प्रश्न जोड़ा गया (प्रश्न # 4)।रणनीति पैटर्न का उपयोग कर जावा में ईमेलर

हाय सब,

मैं अपने आप को एक कस्टम उपयोगिता ईमेल का निर्माण कर रहा हूँ। अब, एकल उत्तरदायित्व सिद्धांत का पालन करने के लिए, मैं निम्नलिखित कक्षाएं प्राप्त करना चाहता हूं: मेलरसेन्डर, मेलप्रोवाइडर और ईमेल ऑब्जेक्ट। MailSender एक प्रतिनिधि के अधिक है, यह नीचे की जाँच:

public class MailSender { 
    private IMailProvider mailProvider; 

    public void setMailProvider (IMailProvider provider) { 
     this.mailProvider = provider; 
    } 

    // option to set it up during construction 
    public MailSender (IMailProvider provider) { 
     this.mailProvider = provider; 
    } 

    public void sendEmail(EmailObject obj) { 
     if(mailProvider == null) 
      throw new RuntimeException("Need a mail provider to send email."); 

     try { 
      mailProvider.send(obj); 
     } catch (Exception e) { 
      // do something here 
     } 
    } 
} 

MailSender एक IMailProvider ईमेल प्रदाता है कि ईमेल भेजने का काम करता है की आवश्यकता है। यह नीचे खोजें:

public interface IMailProvider { 
    public void sendEmail(EmailObject obj); 
} 

public class SMTPEmailProvider implements IMailProvider { 
    public void sendEmail(EmailObject obj) { 
     // use SMTP to send email using passed-in config 
    } 
} 

public class JMSEmailProvider implements IMailProvider { 
    public void sendEmail(EmailObject obj) { 
     // push emails to JMS queue to be picked up by another thread 
    } 
} 

मैं कुछ रणनीतियों कि ऊपर बताया गया है, लेकिन यह किसी भी संख्या के लिए बढ़ाया जा सकता है। चूंकि मेलसेन्डर किसी भी समय अपने प्रदाता को बदल सकता है, यह प्रभावी रूप से रणनीति पैटर्न को लागू करता है?

MailSender sender = new MailSender(new SMTPMailProvider()); 
sender.send(new EmailObject()); 
sender.setMailProvider(new JMSMailProvider()); 
sender.send(new EmailObject()); 

मेरे सवाल कर रहे हैं:

1. मैं रणनीति पैटर्न को लागू किया है

public class EmailObject { 
    private String to; 
    private String from; 
    private String cc; 
    private String subject; 
    private String body; 

    // setters and getters for all 
} 

क्लाइंट कोड तो तरह दिखेगा:

EmailObject प्रासंगिक ईमेल जानकारी युक्त एक POJO है ?
2. क्या यह डिज़ाइन अच्छा है? क्या मेलप्रोवाइडर को किसी ईमेल ऑब्जेक्ट से अवगत होना समझ में आता है?
3. क्या होगा यदि मेरे पास एक नया ईमेल ऑब्जेक्ट था जिसके बाद उसे अनुलग्नक की आवश्यकता थी?
4. क्लाइंट कोड को अब MailSender बनाने से पहले एक विशिष्ट MailProvider प्राप्त करने की आवश्यकता है ... क्या यह समझ में आता है?

उत्तर

7

ठीक है, चलो अपने प्रश्नों के माध्यम से चलो।

1) अस्पष्ट, हाँ। आप तर्क दे सकते हैं कि आपके पास "एल्गोरिदम" या "रणनीतियों" हैं और आप उनके बीच चुन सकते हैं। हालांकि, मैं रणनीति पैटर्न को एल्गोरिदम के लिए प्रासंगिक कुछ के रूप में सोचना पसंद करता हूं। उदाहरण के लिए, खोज परिणाम प्राप्त करने के विभिन्न तरीके। यहां आप विभिन्न एजेंटों से निपट रहे हैं जिन पर आप ईमेल भेजने की भूमिका निभाते हैं। यह एक आम डिजाइन है, लेकिन मुझे यकीन नहीं है कि मैं इसे आवश्यक रूप से रणनीति कहूंगा। किसी भी तरह से, डिज़ाइन पैटर्न आपको सोचने में मदद करने के लिए हैं, आपको किसी विशिष्ट नाम पर लॉक न करें।

2) मुझे लगता है कि डिजाइन उचित है। मैं वास्तविक कक्षाओं के बजाय विशेष रूप से EMailObject के लिए इंटरफेस का उपयोग करता हूं। इसके अलावा, ईमेल ऑब्जेक्ट के लिए एक कारखाना होना चाहिए, न केवल उन्हें नया करें। यह भी बहुत संभावना है कि प्रत्येक प्रदाता अपनी खुद की "ईमेल ऑब्जेक्ट" प्रदान करेगा जिसमें पैकेज विवरण शामिल है। आप सामग्री भेज रहे हैं, न कि "लिफाफा"।

3) कक्षा के बजाए इंटरफेस का उपयोग करने का यह एक और अच्छा कारण है। और आप मेटाडेटा और संभावित अनुलग्नकों के लिए गेटर्स/सेटर्स शामिल करना चाह सकते हैं क्योंकि वे आपके डोमेन (ईमेल) का एक वैध हिस्सा हैं।

+3

इस कथन के लिए +1: "किसी भी तरह से, डिज़ाइन पैटर्न आपको सोचने में मदद करने के लिए हैं, आपको किसी विशिष्ट नाम पर लॉक न करने के लिए।" मुझे यह जानने में थोड़ी देर लग गई कि: ^) – bedwyr

+0

मैं ऐसा करने का एक अच्छा तरीका जानने की कोशिश कर रहा हूं। मेलरसेन्डर को कंक्रीट क्लास के बजाय एक ईमेल ऑब्जेक्ट इंटरफ़ेस मिलता है, प्रदाता जानकारी को "कैसे प्राप्त करता है"? इंटरफ़ेस कंक्रीट कक्षा में जानकारी के लिए एक अनुबंध प्रदान करेगा, लेकिन जब मैं _added_ जानकारी के साथ एक नई वस्तु बनाउंगा तो क्या होगा? एक मूल ईमेल (से, सीसी, विषय, शरीर) के मामले में एक अनुलग्नक (बाइट [] डेटा) के साथ एक ईमेल बनाम? – djunforgetable

+0

आपको यह निर्धारित करना होगा कि प्रत्येक प्रदाता किस परिसर से परिचित है और इंटरफ़ेस में गेटर्स की पेशकश करता है। प्रदाताओं को आम तौर पर केवल ईमेल से निपटने की उम्मीद की जा सकती है, इसलिए आपको जिस ईमेल की आवश्यकता होगी उसे ईमेल में डाल देना होगा। – Uri

0

सबसे महत्वपूर्ण सवाल यहाँ मेरी राय में हैं:

  1. आप वास्तविक ईमेल भेजने के बिना अपने घटक का परीक्षण कर सकते हैं?हां:

    MailSender sender = new MailSender(new FakeMailProvider()); 
    sender.send(new EmailObject()); 
    
  2. क्या आप अपने ईमेल प्रदाताओं को शेष एप्लिकेशन के बिना परीक्षण कर सकते हैं? हाँ:

    SMTPMailProvider provider = new SMTPMailProvider(); 
    provider.send(new EmailObject()); 
    

आपने सफलतापूर्वक प्रेषकों से प्रदाताओं decoupled है।

संपादित करें: प्रश्न 4। ईमेलओब्जेक्ट भेजने से पहले ग्राहक को मेलसेंडर को विशिष्ट MailProvider पास करने की आवश्यकता है। इस कथन को इस तरह से परिवर्तित किया जा सकता है: "ग्राहक ईमेलिंग सेवा ईमेल भेजता है, ईमेल डेटा पास करता है और एक परिवहन चुनता है (ईमेल भेजने का एक तरीका)"। मुझे लगता है कि यह ठीक है, लेकिन यदि आप हर बार परिवहन निर्दिष्ट नहीं करना चाहते हैं, तो आप इसे "... सेवा को कॉन्फ़िगर किए गए परिवहन का उपयोग करके ईमेल भेज सकते हैं" और कॉन्फ़िगरेशन में प्रदाता तत्कालता को स्थानांतरित कर सकते हैं।

+1

क्या आपको लगता है कि क्लाइंट के लिए मेलस्पेंडर में मेलप्रोवाइडर में पास करना होगा? क्या फैक्ट्री या बिल्डर पैटर्न का उपयोग करके इसे पाने का कोई तरीका है? – djunforgetable

+0

बधाई हो, आपने अभी निर्भरता इंजेक्शन की आवश्यकता महसूस की है! मुझे नहीं लगता कि मैं यहां आपके लिए एक मजाक बनाने की कोशिश कर रहा हूं, यह वास्तव में प्रोग्रामर के लिए अगले स्तर की तरह है: http://codebetter.com/blogs/jeremy.miller/archive/2008/11/11/evolution- ऑफ-ए-डेवलपर-इन-सम्मान-टू-डी-आईओसी.एएसपीएक्स – bbmud

+0

@bbmud ठंडा! लेकिन आप डीआई/आईओसी ढांचे के बिना इसे कैसे काम करेंगे? – djunforgetable

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