2009-11-27 15 views
5

इस लक्ष्य को पूरा करने का सामान्य तरीका यहां है:मैं अपने विधि इनपुट पैरामीटर पर मान्य बाधाओं को कैसे रख सकता हूं?

public void myContractualMethod(final String x, final Set<String> y) { 
    if ((x == null) || (x.isEmpty())) { 
     throw new IllegalArgumentException("x cannot be null or empty"); 
    } 
    if (y == null) { 
     throw new IllegalArgumentException("y cannot be null"); 
    } 
    // Now I can actually start writing purposeful 
    // code to accomplish the goal of this method 

मुझे लगता है कि यह समाधान बदसूरत है। आपकी विधियों को विधि के दिल को अस्पष्ट करने, वैध इनपुट पैरामीटर अनुबंध की जांच करने वाले बॉयलरप्लेट कोड से जल्दी भरें।

यहां मैं यह चाहता हूं कि:

public void myContractualMethod(@NotNull @NotEmpty final String x, @NotNull final Set<String> y) { 
    // Now I have a clean method body that isn't obscured by 
    // contract checking 

यदि वे एनोटेशन जेएसआर 303/बीन वैलिडेशन स्पेक की तरह दिखते हैं, तो ऐसा इसलिए है क्योंकि मैंने उन्हें उधार लिया था। दुर्भाग्य से वे इस तरह से काम नहीं कर रहे हैं; वे उदाहरण चरों को एनोटेट करने के लिए हैं, फिर ऑब्जेक्ट को वैधकर्ता के माध्यम से चला रहे हैं।

many Java design-by-contract frameworks में से कौन सा "मेरे जैसा होना" उदाहरण के लिए निकटतम कार्यक्षमता प्रदान करता है? फेंकने वाले अपवाद रनटाइम अपवाद (जैसे IllegalArgumentExceptions) होना चाहिए ताकि encapsulation टूटा नहीं जा सके।

उत्तर

5

यदि आप पूरी तरह से डिज़ाइन-बाय-कॉन्ट्रैक्ट तंत्र की तलाश में हैं तो मैं Wikipedia page for DBC पर सूचीबद्ध कुछ परियोजनाओं पर एक नज़र डालेगा।

यदि आप कुछ आसान खोज रहे हैं, तो आप Google संग्रह से Preconditions कक्षा को देख सकते हैं, जो checkNotNull() विधि प्रदान करता है। तो अगर आप कोड आप के लिए तैनात पुनर्लेखन कर सकते हैं:

public void myContractualMethod(final String x, final Set<String> y) { 
    checkNotNull(x); 
    checkArgument(!x.isEmpty()); 
    checkNotNull(y); 
} 
+0

प्रीकंडिशन। चेक एर्ग्यूमेंट (! X.isEmpty())। –

+1

आह, लाइब्रेरी निर्माता को हमेशा हाथ में रखने में मददगार :) –

0

यह सीधे आपके प्रश्न का उत्तर नहीं है, लेकिन मुझे लगता है कि आपकी समस्या का वह हिस्सा है कि आप मान्यता अति कर रहे हैं। उदाहरण के लिए, आप के साथ पहले टेस्ट की जगह सकता है:

if (x.isEmpty()) { 
    throw new IllegalArgumentException("x cannot be empty"); 
} 

और जावा पर भरोसा फेंकने के लिए एक NullPointerException अगर xnull है। आपको बस अपने "अनुबंध" को बदलने की जरूरत है कि एनपीई को कुछ प्रकार के "फेंक दिया गया है" जिन्हें आप अवैध मानकों के साथ बुलाते हैं।

0

जेरेड ने आपको विभिन्न ढांचे पर इंगित किया जो जावा में डीबीसी के लिए समर्थन जोड़ते हैं।
जो मैंने सबसे अच्छा काम करने के लिए पाया है वह है: बस जावाडोक में अपने अनुबंध को दस्तावेज करें (या जो भी दस्तावेज़ीकरण आप उपयोग करते हैं; डॉक्सिजन को डीबीसी टैग के लिए समर्थन है।)
आपके कोड को बहुत से फेंकने और आपके तर्कों की जांच से गुमराह करना है ' आपके पाठक के लिए वास्तव में सहायक नहीं है। दस्तावेज़ीकरण है।

+1

समस्या तब होती है जब आप अनदेखा करते हैं, या यदि आप याद करते हैं, तो पूर्व शर्त में से एक, तो यह गारंटी नहीं देता कि आपको क्या व्यवहार मिल रहा है। सबसे अच्छा आप एक एनपीई प्राप्त कर सकते हैं, सबसे बुरी स्थिति में आप कुछ यादृच्छिक अपवाद के साथ खत्म हो जाएंगे, इस पर कोई विचार नहीं कि यह क्यों हुआ। –

+0

@ जेरेड मैं सहमत हूं। लेकिन आमतौर पर कोई बेहतर तरीका नहीं है। या तो आप एक भारी ढांचे में आते हैं और सभी सीखने और obfuscation ओवरहेड लेते हैं या आप इसके साथ चिपके रहते हैं। यदि आप वास्तव में डीबीसी का उपयोग करना चाहते हैं तो आप इसे मूल रूप से समर्थन देने वाली भाषा के साथ सर्वश्रेष्ठ हैं। – pmr

2

मैंने Eric Burke द्वारा एक तकनीक देखी है जो लगभग निम्न की तरह है। यह स्थैतिक आयात का एक सुंदर उपयोग है। कोड बहुत अच्छी तरह से पढ़ता है।

विचार प्राप्त करने के लिए, यहां Contract कक्षा है। यह यहां न्यूनतम है, लेकिन जरूरत के रूप में आसानी से भरा जा सकता है।

package net.codetojoy; 

public class Contract { 
    public static void isNotNull(Object obj) { 
     if (obj == null) throw new IllegalArgumentException("illegal null"); 
    } 
    public static void isNotEmpty(String s) { 
     if (s.isEmpty()) throw new IllegalArgumentException("illegal empty string"); 
    } 
} 

और यहां एक उदाहरण उपयोग है। foo() विधि दिखाता स्थिर आयात:

package net.codetojoy; 

import static net.codetojoy.Contract.*; 

public class Example { 
    public void foo(String str) { 
     isNotNull(str); 
     isNotEmpty(str); 
     System.out.println("this is the string: " + str); 
    } 

    public static void main(String[] args) { 
     Example ex = new Example(); 
     ex.foo(""); 
    } 
} 

नोट: जब प्रयोग, ध्यान दें कि there may be a bug आसपास डिफ़ॉल्ट पैकेज में यह कर। मैंने निश्चित रूप से कोशिश कर रहे मस्तिष्क कोशिकाओं को खो दिया है।

+1

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

0

मैं एप-वाइड सुविधा बनाने के लिए पैरामीटर एनोटेशन, प्रतिबिंब और जेनेरिक वैलिडेटर क्लास का उपयोग करूंगा। उदाहरण के लिए, आप की तरह एक वर्ग विधि कोड कर सकते हैं:

.. MyMethod (@notNull स्ट्रिंग एक्स, @notNullorZero स्ट्रिंग वाई) {

if (Validator.ifNotContractual(getParamDetails()) { 
    raiseException.. 
    or 
    return .. 
} 

}

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

1

सादा जावा के रूप में लागू एक छोटा Java Argument Validation पैकेज है। यह कई मानक चेक/सत्यापन के साथ आता है। और उन मामलों के लिए जहां किसी को अपने स्वयं के विशिष्ट मान्यताओं की आवश्यकता होती है, यह कुछ सहायक तरीकों के साथ आता है। कई बार होने वाली मान्यताओं के लिए, बस अपने आप के साथ इंटरफ़ेस ArgumentValidation का विस्तार करें और क्लास ArgumentValidationImpl से विस्तारित कार्यान्वयन वर्ग बनाएं।

+0

यह आपको जाने के लिए कुछ उदाहरणों के साथ आता है। http://java-arg-val.sourceforge.net/usage.html (इस पृष्ठ पर 2 उदाहरण, और जावा डॉक में 3 (दिए गए पृष्ठ के शीर्ष पर उनके संदर्भ) – Verhagen

0

पूरी तरह से काम करने वाला समाधान नहीं है, लेकिन जेएसआर -303 में method-level validation extension का प्रस्ताव है। चूंकि यह अभी सिर्फ एक विस्तार प्रस्ताव है, जेएसआर -303 के कार्यान्वयन इसे अनदेखा करने के लिए स्वतंत्र हैं। एक कार्यान्वयन ढूँढना थोड़ा और मुश्किल है। मुझे नहीं लगता कि हाइबरनेट वैलिडेटर अभी तक इसका समर्थन करता है, लेकिन मेरा मानना ​​है कि agimatec-validation में प्रयोगात्मक समर्थन है। मैंने इस उद्देश्य के लिए या तो उपयोग नहीं किया है, इसलिए मुझे नहीं पता कि वे कितनी अच्छी तरह से काम करते हैं। हालांकि, अगर कोई इसे जाने देता है तो मुझे पता लगाने में दिलचस्पी होगी।

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

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