2016-03-22 4 views
7

मैं उन वर्गों में से एक के साथ एक बहुत ही खास स्थिति में हूं जिसमें मैं कोडिंग कर रहा हूं। new User(): कई स्थितियों में, जहां मैं सिर्फ प्रकार User के एक खाली वस्तु की जरूरत है और इसलिए सिर्फ डिफ़ॉल्ट निर्माता का उपयोग कर इसे बनाने देखते हैं मेरी कोड के भीतरडिज़ाइन पैटर्न - केवल कुछ परिस्थितियों में ऑब्जेक्ट विशेषताओं को कैसे लागू करें (बिल्डर पैटर्न, निर्भरता इंजेक्शन)

public class User { 
    private long id; // + getters and setters 
    private boolean isDeletable; // + getters and setters 
    private String name; // + getters and setters 
    private String password; // + getters and setters 
    private String email; // + getters and setters 
    private String authenticationRealm; // + getters and setters 
    private String displayName; // + getters and setters 
    private Date deletedDate; // + getters and setters 
} 

: मैं इस वर्ग User कहा जाता है कि इस तरह दिखता है।

हालांकि, मेरे पास CreateUserRequest नामक एक और वर्ग है जो सर्वर में उपयोगकर्ता को बनाने के लिए एक आरईएसटी अनुरोध मॉडल करता है। न्यूनतम पेलोड में name, password, email, और authenticationRealm JSON प्रारूप में भेजे गए गुणों में अवश्य होना चाहिए।

public CreateUserRequest(User user) { 
    if(user.getName() == null || user.getPassword() == null || user.getEmail() == null || user.getAuthenticationRealm() == null) 
     throw new RuntimeException("Not enough attributes in User object. Minimum: name, password, e-mail and authentication realm."); 
} 

यह ठीक काम कर रहा है लेकिन कुछ खुजली है ... मैं एक सुरक्षित तरीके से इस लागू करने के लिए करना चाहते हैं:

अभी मैं अनुरोध के निर्माता में इन मानकों के लिए देख कर इसकी हैंडलिंग हूँ , ताकि कोड उन अपवादों को लागू कर सके जो अपवाद को फेंकने की कोई संभावना नहीं है।

मुझे लगता है कि डिज़ाइन पैटर्न के साथ ऐसा करने का एक बेहतर तरीका होना चाहिए। मैंने UserRequestBuilder वर्ग बनाने का विचार किया, लेकिन यह संभवतः build() विधि में अपवाद फेंकने का भी अर्थ होगा (अन्यथा, क्या कोई तरीका है कि मैं गारंटी दे सकता हूं कि गुण build() से पहले आबादी वाले हैं?)। निर्भरता इंजेक्शन भी एक संभावना की तरह लगता है, लेकिन मुझे यकीन नहीं है कि मैं इसे इस विशेष उदाहरण में कैसे रखूंगा ...

कोई विचार?

+3

एक अलग ऑब्जेक्ट की तरह लगता है, एक CreateUser ऑब्जेक्ट शायद उसमें एक निर्माता है और आपूर्ति किए गए मानों को मान्य करता है। किसी भी कारण से उन्हें एक ही कक्षा के आधार पर होना चाहिए क्योंकि वे दो अलग-अलग कार्य कर रहे हैं? – dbugger

+1

मेरे तत्काल विचार उपयोगकर्ता वर्ग पर एक नया isValidUserRequest() विधि जोड़ देंगे। यह सोचकर कि उपयोगकर्ता वर्ग को खुद को तय करना चाहिए यदि यह वैध है या अनुरोध में उपयोग के लिए नहीं है। –

+0

टिप्पणी @dbugger के लिए धन्यवाद। हां - कई आरईएसटी कॉल या तो 'उपयोगकर्ता' वर्ग के समान गुणों के साथ जेएसओएन ऑब्जेक्ट्स का उत्पादन या उपभोग करते हैं (यानी उपयोगकर्ता वर्ग रिमोट इकाई का प्रतिनिधित्व करता है)। कक्षाएं वास्तव में विभिन्न कार्यों का प्रदर्शन नहीं कर रही हैं। 'CreateUserRequest' क्लास एक आरईएसटी कॉल बनाता है जो JSON प्रारूप में अपने पेलोड में' उपयोगकर्ता 'ऑब्जेक्ट पास करता है। – Phil

उत्तर

7

आपकी आरईएसटी सेवाएं उपयोगकर्ता DTO पर कैसे संचालित करती हैं? (बेशक, उपयोगकर्ता डीटीओ को उपयोगकर्ता के उप-वर्ग के साथ प्रतिस्थापित किया जा सकता है)।

आप उपयोगकर्ता डीटीओ पर @NonNull के साथ फ़ील्ड, सेटर्स या कन्स्ट्रक्टर पैरामीटर एनोटेट कर सकते हैं और उपयोगकर्ता डीटीओ को नाम पासवर्ड, ईमेल इत्यादि के बजाय शून्य मानों को पार करते समय Checker Framework समस्या संकलक चेतावनियां दे सकते हैं।

Mapstruct की तरह एक रूपरेखा का उपयोग करना, बाकी सेवाओं DTOs और बैकएंड वस्तुओं के बीच मानचित्रण बहुत आसान है:

@Mapper 
public interface UserMapper { 

    public static final UserMapper INSTANCE = Mappers.getMapper(UserMapper.class); 

    UserDTO map(User user); 

    User map(UserDTO userDTO); 
} 

कोड संकलन पर एक UserMapper कार्यान्वयन निर्दिष्ट तरीकों के लिए स्वत: जनरेट कोड के साथ, उत्पन्न होगा ऊपर (- और स्वत: जेनरेट कोड आसानी से नामक गेटर्स और सेटर्स नामक जोड़े। आप इसे स्वयं कर सकते हैं, लेकिन कई डीटीओ/संस्थाओं के साथ समय लेने और उबाऊ हो जाता है)।

डीटीओ में आप उन सभी क्षेत्रों को बाहर कर सकते हैं जिन्हें आप बेनकाब नहीं करना चाहते हैं।

Ps। उपर्युक्त का मेरा उपयोग यह है: मैं जर्सी के आधार पर एक आरईएसटी सर्वर बना रहा हूं, यानी जेएक्स-आरएस के संदर्भ कार्यान्वयन। यह प्रोजेक्ट, इसे ए कॉल करें, केवल डीटीओ के बारे में जानता है। आरईएसटी विधियों को एक अन्य प्रोजेक्ट बी में कॉल किया जाता है, जो डेटाबेस से ऑब्जेक्ट्स को पुनर्प्राप्त करता है, और उन्हें संबंधित डीटीओ में मानचित्रित करता है, जिसे तब परियोजना ए में वापस कर दिया जाता है। इस पैटर्न के कारण का एक हिस्सा यह है कि ऐतिहासिक कारणों से प्रोजेक्ट बी की इकाइयां हैं विधियों/कार्यक्षमता के साथ अव्यवस्थित, जो परियोजना ए के संपर्क में नहीं आना चाहिए।सैनिटी चेक (जेएसओएन से डीटीओ) के लिए, जर्सी बीन वैलिडेशन का समर्थन करता है, जो कहने के लिए है कि फ्रेमवर्क प्रत्येक शेष संसाधन के इनपुट बीन्स को मान्य करेगा यदि वे @ वालिद के साथ एनोटेटेड हैं। अपनी खुद की कस्टम एनोटेशन बनाना भी संभव है, जिसमें एक कॉन्स्ट्रेन्ट वैलिडेटेटर परिभाषित किया गया है। बीन सत्यापन फ्रेमवर्क एनोटेटेड जर्सी आरईएसटी विधि पैरामीटर पर इन बाधाओं की जांच करेगा। https://jersey.java.net/documentation/latest/bean-validation.html#d0e13690

+0

बहुत ही रोचक दृष्टिकोण, @ हार्वियन। अगर मैं काम करता हूं तो मैं इसे आज़माकर इसे उत्तर के रूप में चिह्नित करूंगा। धन्यवाद। – Phil

+0

मैंने एक बहुत ही समान दृष्टिकोण का पालन किया और यह काम किया। धन्यवाद। – Phil

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