क्या एक अपरिवर्तनीय वस्तु में तर्क सत्यापन और फ़ील्ड आरंभीकरण का परीक्षण करने का एक आसान तरीका है?


20

मेरे डोमेन में इस तरह के बहुत सारे सरल अपरिवर्तनीय वर्ग हैं:

public class Person
{
    public string FullName { get; }
    public string NameAtBirth { get; }
    public string TaxId { get; }
    public PhoneNumber PhoneNumber { get; }
    public Address Address { get; }

    public Person(
        string fullName,
        string nameAtBirth,
        string taxId,
        PhoneNumber phoneNumber,
        Address address)
    {
        if (fullName == null)
            throw new ArgumentNullException(nameof(fullName));
        if (nameAtBirth == null)
            throw new ArgumentNullException(nameof(nameAtBirth));
        if (taxId == null)
            throw new ArgumentNullException(nameof(taxId));
        if (phoneNumber == null)
            throw new ArgumentNullException(nameof(phoneNumber));
        if (address == null)
            throw new ArgumentNullException(nameof(address));

        FullName = fullName;
        NameAtBirth = nameAtBirth;
        TaxId = taxId;
        PhoneNumber = phoneNumber;
        Address = address;
    }
}

अशक्त चेक और प्रॉपर्टी इनिशियलाइज़ेशन लिखना पहले से ही बहुत थकाऊ हो रहा है, लेकिन वर्तमान में मैं इन वर्गों में से प्रत्येक के लिए यूनिट टेस्ट लिखता हूं ताकि यह सत्यापित किया जा सके कि तर्क सत्यापन सही ढंग से काम करता है और सभी संपत्तियों को आरंभीकृत किया जाता है। यह बहुत ही उबाऊ व्यस्तता के साथ लगता है जैसे कि लाभहीन लाभ के साथ।

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


यहाँ मैं अब जवाब के आधार पर क्या है।

मैं इस तरह देखने के लिए अशक्त जांच और संपत्ति आरंभीकरण को आसान बना सकता है:

FullName = fullName.ThrowIfNull(nameof(fullName));
NameAtBirth = nameAtBirth.ThrowIfNull(nameof(nameAtBirth));
TaxId = taxId.ThrowIfNull(nameof(taxId));
PhoneNumber = phoneNumber.ThrowIfNull(nameof(phoneNumber));
Address = address.ThrowIfNull(nameof(address));

रॉबर्ट हार्वे द्वारा निम्नलिखित कार्यान्वयन का उपयोग करना :

public static class ArgumentValidationExtensions
{
    public static T ThrowIfNull<T>(this T o, string paramName) where T : class
    {
        if (o == null)
            throw new ArgumentNullException(paramName);

        return o;
    }
}

अशक्त जाँच का उपयोग करना आसान GuardClauseAssertionहै AutoFixture.Idioms(सुझाव के लिए धन्यवाद, एसेन स्कोव पेडर्सन ):

var fixture = new Fixture().Customize(new AutoMoqCustomization());
var assertion = new GuardClauseAssertion(fixture);
assertion.Verify(typeof(Address).GetConstructors());

इसे और भी संकुचित किया जा सकता है:

typeof(Address).ShouldNotAcceptNullConstructorArguments();

इस विस्तार विधि का उपयोग करना:

public static void ShouldNotAcceptNullConstructorArguments(this Type type)
{
    var fixture = new Fixture().Customize(new AutoMoqCustomization());
    var assertion = new GuardClauseAssertion(fixture);

    assertion.Verify(type.GetConstructors());
}

3
शीर्षक / टैग के बारे में (यूनिट) फील्ड वैल्यू का परीक्षण करता है जो ऑब्जेक्ट के पोस्ट-कंस्ट्रक्शन यूनिट टेस्टिंग से संबंधित है, लेकिन कोड स्निपेट इनपुट तर्क / पैरामीटर सत्यापन दर्शाता है; ये समान अवधारणाएँ नहीं हैं।
एरिक Eidt

2
FYI करें, आप एक T4 टेम्पलेट लिख सकते हैं जो इस तरह के बॉयलरप्लेट को आसान बना देगा। (आप भी string.IsEmpty () == बातिल परे सोच सकते हैं।)
एरिक Eidt

1
क्या आपने स्वत: स्फूर्त मुहावरों पर एक नज़र डाली है? nuget.org/packages/AutoFixture.Idioms
स्कोव पेडर्सन


1
आप Fody / NullGuard का भी उपयोग कर सकते हैं , हालांकि ऐसा लगता है कि इसमें डिफ़ॉल्ट-अनुमति मोड नहीं है।
बॉब

जवाबों:


5

मैंने इस तरह के मामलों के लिए वास्तव में एक टी 4 टेम्पलेट बनाया। अपरिवर्तनीय वर्गों के लिए बहुत सारे बॉयलरप्लेट लिखने से बचने के लिए।

https://github.com/xaviergonz/T4Immutable T4Immutable C # .NET ऐप्स के लिए एक T4 टेम्प्लेट है जो अपरिवर्तनीय वर्गों के लिए कोड उत्पन्न करता है।

यदि आप इसका उपयोग करते हैं तो विशेष रूप से गैर अशक्त परीक्षणों के बारे में बात करना:

[PreNotNullCheck, PostNotNullCheck]
public string FirstName { get; }

निर्माणकर्ता यह होगा:

public Person(string firstName) {
  // pre not null check
  if (firstName == null) throw new ArgumentNullException(nameof(firstName));

  // assignations + PostConstructor() if needed

  // post not null check
  if (this.FirstName == null) throw new NullReferenceException(nameof(this.FirstName));
}

यह कहने के बाद, यदि आप अशक्त जाँच के लिए JetBrains एनोटेशन का उपयोग करते हैं, तो आप यह भी कर सकते हैं:

[JetBrains.Annotations.NotNull, ConstructorParamNotNull]
public string FirstName { get; }

और निर्माणकर्ता यह होगा:

public Person([JetBrains.Annotations.NotNull] string firstName) {
  // pre not null check is implied by ConstructorParamNotNull
  if (firstName == null) throw new ArgumentNullException(nameof(firstName));

  FirstName = firstName;
  // + PostConstructor() if needed

  // post not null check implied by JetBrains.Annotations.NotNull on the property
  if (this.FirstName == null) throw new NullReferenceException(nameof(this.FirstName));
}

इसके अलावा इस से कुछ अधिक विशेषताएं हैं।


धन्यवाद। मैंने अभी इसकी कोशिश की है और इसने पूरी तरह से काम किया है। मैं इसे स्वीकृत उत्तर के रूप में चिह्नित करता हूं क्योंकि यह मूल प्रश्न में सभी मुद्दों को संबोधित करता है।
बोटॉन्ड बालाज़

16

आप एक सरल रीफैक्टरिंग के साथ थोड़ा सुधार कर सकते हैं जो उन सभी बाड़ को लिखने की समस्या को कम कर सकते हैं। सबसे पहले, आपको इस एक्सटेंशन विधि की आवश्यकता है:

internal static T ThrowIfNull<T>(this T o, string paramName) where T : class
{
    if (o == null)
        throw new ArgumentNullException(paramName);

    return o;
}

आप तब लिख सकते हैं:

public class Person
{
    public string FullName { get; }
    public string NameAtBirth { get; }
    public string TaxId { get; }
    public PhoneNumber PhoneNumber { get; }
    public Address Address { get; }

    public Person(
        string fullName,
        string nameAtBirth,
        string taxId,
        PhoneNumber phoneNumber,
        Address address)
    {
        FullName = fullName.ThrowIfNull(nameof(fullName));
        NameAtBirth = nameAtBirth.ThrowIfNull(nameof(nameAtBirth));
        TaxId = taxId.ThrowIfNull(nameof(taxId));
        PhoneNumber = phoneNumber.ThrowIfNull(nameof(fullName));
        Address = address.ThrowIfNull(nameof(address));
    }
}

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

अन्य तकनीक अवधारणा में अधिक सुरुचिपूर्ण हैं, लेकिन निष्पादन में उत्तरोत्तर अधिक जटिल हैं, जैसे कि एक [NotNull]विशेषता के साथ पैरामीटर को सजाने , और इस तरह रिफ्लेक्ट का उपयोग करना ।

कहा कि, आपको इन सभी परीक्षणों की आवश्यकता नहीं हो सकती है, जब तक कि आपका वर्ग सार्वजनिक-सामना करने वाले एपीआई का हिस्सा नहीं है।


3
अजीब बात है कि यह डाउनवोट किया गया था। यह सबसे अपवित्र उत्तर द्वारा प्रदान किए गए दृष्टिकोण के समान है, सिवाय इसके कि यह रोसलिन पर निर्भर नहीं करता है।
रॉबर्ट हार्वे

मुझे इस बारे में पसंद नहीं है कि यह निर्माणकर्ता के संशोधनों के लिए असुरक्षित है।
jpmc26

@ jpmc26: इसका क्या मतलब है?
रॉबर्ट हार्वे

1
जैसा कि मैंने आपके उत्तर को पढ़ा है, यह सुझाव दे रहा है कि आप कंस्ट्रक्टर का परीक्षण न करें , लेकिन इसके बजाय आप प्रत्येक पैरामीटर पर कॉल की गई कुछ सामान्य विधि बनाएं और उसका परीक्षण करें । यदि आप एक नई संपत्ति / तर्क जोड़ी जोड़ते हैं और nullनिर्माणकर्ता के तर्क पर परीक्षण करना भूल जाते हैं , तो आपको एक असफल परीक्षा नहीं मिलेगी।
jpmc26

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

7

अल्पावधि में, इस तरह के परीक्षण लिखने की थकान के बारे में आप बहुत कुछ नहीं कर सकते हैं। हालांकि, सी # (v7) की अगली रिलीज के भाग के रूप में लागू होने के कारण फेंक अभिव्यक्ति के साथ आने में कुछ मदद है, संभवतः अगले कुछ महीनों में:

public class Person
{
    public string FullName { get; }
    public string NameAtBirth { get; }
    public string TaxId { get; }
    public PhoneNumber PhoneNumber { get; }
    public Address Address { get; }

    public Person(
        string fullName,
        string nameAtBirth,
        string taxId,
        PhoneNumber phoneNumber,
        Address address)
    {
        FullName = fullName ?? throw new ArgumentNullException(nameof(fullName));
        NameAtBirth = nameAtBirth ?? throw new ArgumentNullException(nameof(nameAtBirth));
        TaxId = taxId ?? throw new ArgumentNullException(nameof(taxId)); ;
        PhoneNumber = phoneNumber ?? throw new ArgumentNullException(nameof(phoneNumber)); ;
        Address = address ?? throw new ArgumentNullException(nameof(address)); ;
    }
}

ट्राई रोसलिन वेबैप के जरिए आप थ्रो एक्सप्रेशंस के साथ प्रयोग कर सकते हैं ।


बहुत अधिक कॉम्पैक्ट, धन्यवाद। आधी कई लाइनों के रूप में। C # 7 के लिए आगे देख रहे हैं!
बोटॉन्ड बालाज़ 17

@ BotondBalázs आप इसे VS15 पूर्वावलोकन में अभी आज़मा सकते हैं यदि आप चाहते हैं
user1306322

7

मुझे आश्चर्य है कि किसी ने भी NullGuard का उल्लेख नहीं किया है। अभी तक। यह NuGet के माध्यम से उपलब्ध है और संकलन समय के दौरान IL में उन अशक्त जांचों को स्वचालित रूप से बुन देगा।

तो आपका कंस्ट्रक्टर कोड बस होगा

public Person(
    string fullName,
    string nameAtBirth,
    string taxId,
    PhoneNumber phoneNumber,
    Address address)
{
    FullName = fullName;
    NameAtBirth = nameAtBirth;
    TaxId = taxId;
    PhoneNumber = phoneNumber;
    Address = address;
}

और NullGuard आपके लिए उन अशक्त जांचों को जोड़ देगा जो आपने लिखी हैं।

नोट हालांकि, कि NullGuard है ऑप्ट-आउट , यह है कि, यह उन अशक्त चेकों में जोड़ देगा हर विधि और निर्माता तर्क, संपत्ति गेटर और सेटर और यहां तक कि विधि वापसी मूल्यों की जाँच जब तक आप स्पष्ट अनुमति देने के साथ एक शून्य मान [AllowNull]विशेषता।


धन्यवाद, यह एक बहुत अच्छा सामान्य समाधान जैसा दिखता है। हालांकि यह बहुत दुर्भाग्यपूर्ण है कि यह डिफ़ॉल्ट रूप से भाषा व्यवहार को संशोधित करता है। मैं इसे और अधिक पसंद करूँगा यदि यह एक [NotNull]विशेषता जोड़कर काम करता है बजाय अशक्त डिफ़ॉल्ट होने की अनुमति के।
बोटॉन्ड बालाज़्स

@ BotondBalázs: PostSharp में अन्य पैरामीटर सत्यापन विशेषताओं के साथ यह है। हालांकि Fody के विपरीत यह मुफ़्त नहीं है। इसके अलावा, उत्पन्न कोड PostSharp DLL में कॉल करेगा, इसलिए आपको अपने उत्पाद के साथ उन लोगों को शामिल करना होगा। Fody संकलन के दौरान केवल अपना कोड चलाएगा और रनटाइम के लिए आवश्यक नहीं होगा।
रोमन रेनर

@ BotondBalázs: मुझे भी यह पहली बार में अजीब लगा कि NullGuard डिफ़ॉल्ट रूप से लागू होता है लेकिन यह वास्तव में समझ में आता है। किसी भी उचित कोड आधार में, शून्य की अनुमति देने से अशक्त नल की जांच करने की तुलना में बहुत कम सामान्य होना चाहिए । यदि आप वास्तव में कहीं अनुमति देना चाहते हैं, तो ऑप्ट-आउट दृष्टिकोण आपको इसके साथ बहुत गहन होने के लिए मजबूर करता है।
रोमन रेनर

5
हां, यह वाजिब है लेकिन यह प्रिंसिपल ऑफ लिस्ट एस्टनमेंट का उल्लंघन करता है । यदि कोई नया प्रोग्रामर यह नहीं जानता है कि प्रोजेक्ट NullGuard का उपयोग करता है, तो वे एक बड़े आश्चर्य में हैं! वैसे, मुझे समझ में नहीं आता कि या तो यह एक बहुत ही उपयोगी उत्तर है।
बोटॉन्ड बालाज़ 22

1
@ BotondBalázs / रोमन, ऐसा लगता है कि NullGuard में एक नया स्पष्ट मोड है, जो डिफ़ॉल्ट रूप से काम करने के तरीके को बदल देता है
Kyle W

5

क्या यह इन सभी परीक्षणों को लिखने के लायक है?

नहीं, शायद नहीं। क्या संभावना है कि आप उस पर शिकंजा कसने जा रहे हैं? क्या संभावना है कि कुछ शब्दार्थ आपके नीचे से बदल जाएंगे? अगर कोई इसे पंगा लेता है तो क्या प्रभाव पड़ता है?

यदि आप किसी ऐसी चीज़ के लिए समय परीक्षण का एक गुच्छा खर्च कर रहे हैं जो शायद ही कभी टूटेगा, और एक तुच्छ निर्धारण है अगर यह किया ... शायद इसके लायक नहीं है।

क्या इस तरह की कक्षाओं के लिए कोड जनरेटर लिखना बेहतर होगा, जिसमें से प्रत्येक के लिए परीक्षण लिखने से बचें?

शायद? इस तरह की चीज को प्रतिबिंब के साथ आसानी से किया जा सकता है। कुछ विचार करने के लिए वास्तविक कोड के लिए कोड पीढ़ी कर रहा है, इसलिए आपके पास एन कक्षाएं नहीं हैं जो मानवीय त्रुटि हो सकती हैं। बग की रोकथाम> बग का पता लगाना।


धन्यवाद। शायद मैं अपने प्रश्न में पर्याप्त स्पष्ट नहीं था, लेकिन मेरा मतलब एक जनरेटर लिखना था जो अपरिवर्तनीय वर्ग उत्पन्न करता है, न कि उनके लिए परीक्षण
बॉटॉन्ड बैलाज़

2
मैंने भी कई बार देखा है कि if...throwउनके पास ThrowHelper.ArgumentNull(myArg, "myArg")इस तरह का तर्क है, तर्क अभी भी है और आप कोड कवरेज पर डिंग नहीं करते हैं। जहां ArgumentNullविधि करेंगे if...throw
मैथ्यू

2

क्या यह इन सभी परीक्षणों को लिखने के लायक है?

नहीं।
क्योंकि मुझे पूरा यकीन है कि आपने उन गुणों का परीक्षण तर्क के कुछ अन्य परीक्षणों के माध्यम से किया है जहाँ उन वर्गों का उपयोग किया जाता है।

उदाहरण के लिए, आपके पास फ़ैक्टरी वर्ग के लिए परीक्षण हो सकते हैं जिनके पास उन गुणों के आधार पर दावा है (उदाहरण के लिए ठीक से असाइन किया गया है Name लिए संपत्ति उदाहरण)।

यदि उन वर्गों को सार्वजनिक एपीआई से अवगत कराया जाता है जो कुछ तीसरे भाग / अंतिम उपयोगकर्ता (@EJoshua धन्यवाद के लिए धन्यवाद) द्वारा उपयोग किया जाता है, तो उम्मीद के लिए परीक्षण ArgumentNullExceptionउपयोगी हो सकते हैं।

C # 7 की प्रतीक्षा करते समय आप एक्सटेंशन विधि का उपयोग कर सकते हैं

public MyClass(string name)
{
    name.ThrowArgumentNullExceptionIfNull(nameof(name));
}

public static void ThrowArgumentNullExceptionIfNull(this object value, string paramName)
{
    if(value == null)
        throw new ArgumentNullException(paramName);
}

परीक्षण के लिए आप एक पैरामीटर परीक्षण पद्धति का उपयोग कर सकते हैं जो कि nullप्रत्येक पैरामीटर के लिए संदर्भ बनाने के लिए और अपेक्षित अपवाद के लिए अभिकथन के लिए प्रतिबिंब का उपयोग करता है।


1
संपत्ति की प्रारंभिक जांच नहीं करने के लिए यह एक ठोस तर्क है।
Botond Balázs

यह इस बात पर निर्भर करता है कि आप कोड का उपयोग कैसे कर रहे हैं। यदि कोड एक सार्वजनिक-सामना करने वाली लाइब्रेरी का हिस्सा है, तो आपको कभी भी अन्य लोगों पर आंख बंद करके भरोसा नहीं करना चाहिए कि आपकी लाइब्रेरी कैसे है (खासकर यदि उनके पास स्रोत कोड तक पहुंच नहीं है); हालाँकि, अगर यह ऐसा कुछ है जो आप केवल आंतरिक रूप से अपने स्वयं के कोड का काम करने के लिए उपयोग करते हैं, तो आपको यह जानना चाहिए कि अपने कोड का उपयोग कैसे करें, इसलिए चेक का उद्देश्य कम है।
EJoshuaS -

2

आप हमेशा निम्नलिखित की तरह एक विधि लिख सकते हैं:

// Just to illustrate how to call this
private static void SomeMethod(string a, string b, string c, string d)
    {
        ValidateArguments(a, b, c, d);
        // ...
    }

    // This is the one to use as a utility function
    private static void ValidateArguments(params object[] args)
    {
        for (int i = 0; i < args.Length; i++)
        {
            if (args[i] == null)
            {
                StackTrace trace = new StackTrace();
                // Get the method that called us
                MethodBase info = trace.GetFrame(1).GetMethod();

                // Get information on the parameter that is null so we can add its name to the exception
                ParameterInfo param = info.GetParameters()[i];

                // Raise the exception on behalf of the caller
                throw new ArgumentNullException(param.Name);
            }
        }
    }

कम से कम, अगर आप कई तरीकों से इस प्रकार के सत्यापन की आवश्यकता है, तो आप कुछ टाइपिंग बचा लेंगे। बेशक, यह समाधान मानता है कि आपके विधि का कोई भी पैरामीटर नहीं हो सकता हैnull , लेकिन आप इसे बदलने के लिए संशोधित कर सकते हैं कि यदि आप चाहें तो।

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

// Note that we already know based on the previous condition that args[i] is not null
else if (args[i].GetType() == typeof(string))
            {
                string argCast = arg as string;

                if (!argCast.Trim().Any())
                {
                    ParameterInfo param = GetParameterInfo(i);

                    throw new ArgumentException(param.Name + " is empty or consists only of whitespace");
                }
            }

GetParameterInfo पद्धति मैं मूल रूप से प्रतिबिंब को संदर्भित करता है (ताकि मुझे एक ही चीज़ को बार-बार टाइप न करना पड़े, जो DRY सिद्धांत का उल्लंघन होगा ):

private static ParameterInfo GetParameterInfo(int index)
    {
        StackTrace trace = new StackTrace();

        // Note that we have to go 2 methods back to get the ValidateArguments method's caller
        MethodBase info = trace.GetFrame(2).GetMethod();

        // Get information on the parameter that is null so we can add its name to the exception
        ParameterInfo param = info.GetParameters()[index];

        return param;
    }

1
इसे क्यों ठुकराया जा रहा है? यह बहुत बुरा नहीं है
Gaspa79

0

मैं निर्माणकर्ता से अपवादों को फेंकने का सुझाव नहीं देता। समस्या यह है कि आपके पास इसका परीक्षण करने के लिए एक कठिन समय होगा क्योंकि आपको वैध मापदंडों को पास करना होगा, यहां तक ​​कि वे आपके परीक्षण के लिए अप्रासंगिक हैं।

उदाहरण के लिए: यदि आप परीक्षण करना चाहते हैं कि क्या तीसरा पैरामीटर एक अपवाद फेंकता है तो आपको पहले और दूसरे में सही तरीके से पास करना होगा। इसलिए आपका परीक्षण अब अलग नहीं किया गया है। जब पहले और दूसरे पैरामीटर की अड़चनें बदल जाती हैं तो यह टेस्ट केस फेल हो जाता है यहां तक ​​कि यह तीसरे पैरामीटर को भी परखता है।

मैं जावा सत्यापन एपीआई का उपयोग करने और सत्यापन प्रक्रिया को बाहरी करने का सुझाव देता हूं। मैं चार जिम्मेदारियों (कक्षाओं) को शामिल करने का सुझाव देता हूं:

  1. जावा सत्यापन के साथ एक सुझाव ऑब्जेक्ट ने एक मान्य विधि के साथ मापदंडों को एनोटेट किया जो कि सेट ऑफ कॉन्स्ट्रेविविलेशन को लौटाता है। एक फायदा यह है कि आप मान्य होने के लिए इस ऑब्जेक्ट के बिना पास कर सकते हैं। आप तब तक सत्यापन में देरी कर सकते हैं जब तक कि यह डोमेन ऑब्जेक्ट को इंस्टेंट करने की कोशिश किए बिना neccessary न हो। सत्यापन ऑब्जेक्ट को विभिन्न परतों में उपयोग किया जा सकता है क्योंकि यह एक POJO है जिसमें कोई परत विशिष्ट ज्ञान नहीं है। यह सार्वजनिक API का हिस्सा हो सकता है।

  2. डोमेन ऑब्जेक्ट के लिए एक कारखाना जो मान्य ऑब्जेक्ट बनाने के लिए ज़िम्मेदार है। आप सुझाव ऑब्जेक्ट में पास करते हैं और कारखाना सत्यापन को कॉल करेगा और सब कुछ ठीक होने पर डोमेन ऑब्जेक्ट बनाएगा।

  3. डोमेन ऑब्जेक्ट ही जो अन्य डेवलपर्स के लिए तात्कालिकता के लिए ज्यादातर अप्राप्य होना चाहिए। परीक्षण के प्रयोजनों के लिए मेरा सुझाव है कि इस वर्ग को पैकेज दायरे में रखा जाए।

  4. कंक्रीट डोमेन ऑब्जेक्ट को छिपाने और गलत उपयोग करने के लिए एक सार्वजनिक डोमेन इंटरफ़ेस।

मैं अशक्त मूल्यों की जाँच करने का सुझाव नहीं देता। जैसे ही आप डोमेन लेयर में आते हैं, आपको अशक्त या वापस लौटने से छुटकारा मिल जाता है, जब तक कि आपके पास ऑब्जेक्ट चेन नहीं होती हैं, जो एकल ऑब्जेक्ट्स के लिए समाप्त होती हैं या खोज कार्य करती हैं।

एक अन्य बिंदु: जितना संभव हो उतना कम कोड लिखना कोड गुणवत्ता के लिए मीट्रिक नहीं है। 32k खेल प्रतियोगिताओं के बारे में सोचो। वह कोड सबसे कॉम्पैक्ट है, लेकिन आपके पास सबसे गड़बड़ कोड भी हो सकता है क्योंकि यह केवल तकनीकी मुद्दों की परवाह करता है और शब्दार्थों की परवाह नहीं करता है। लेकिन शब्दार्थ वे बिंदु हैं जो चीजों को व्यापक बनाते हैं।


1
मैं सम्मानपूर्वक आपके अंतिम बिंदु से असहमत हूं। 100 वीं बार एक ही बॉयलरप्लेट टाइप करने के नहीं करता मदद एक गलती कर की संभावना को कम। सोचिए अगर यह जावा होता तो C # नहीं। मुझे प्रत्येक संपत्ति के लिए एक बैकिंग फ़ील्ड और एक गेट्टर विधि को परिभाषित करना होगा। कोड पूरी तरह से अपठनीय हो जाएगा और जो महत्वपूर्ण है वह क्लंकी अवसंरचना द्वारा अस्पष्ट होगा।
बोटॉन्ड बालाज़्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.