जब एक मूल्य सार्थक रूप से अनुपस्थित हो सकता है तो एक नया बुलियन क्षेत्र एक शून्य संदर्भ से बेहतर है?


39

उदाहरण के लिए, मान लीजिए कि मेरे पास एक वर्ग है Member, जिसमें एक अंतिम बदलाव है।

class Member{
  .
  .
  .
  constructor(){
    this.lastChangePasswordTime=null,
  }
}

जिसका LastChangePasswordTime सार्थक अनुपस्थित हो सकता है, क्योंकि कुछ सदस्य कभी भी अपना पासवर्ड नहीं बदल सकते हैं।

लेकिन अगर नुल्स बुराई के अनुसार , एक मूल्य सार्थक अनुपस्थित हो सकता है तो क्या उपयोग किया जाना चाहिए? और https://softwareengineering.stackexchange.com/a/12836/248528 , मुझे सार्थक अनुपस्थित मान का प्रतिनिधित्व करने के लिए अशक्त का उपयोग नहीं करना चाहिए। इसलिए मैं एक बुलियन ध्वज जोड़ने की कोशिश करता हूं:

class Member{
  .
  .
  .
  constructor(){
    this.isPasswordChanged=false,
    this.lastChangePasswordTime=null,
  }
}

लेकिन मुझे लगता है कि यह काफी पुराना है क्योंकि:

  1. जबPasswordChanged झूठा हो, lastChangePasswordTime को अशक्त होना चाहिए, और lastChangePasswordTime == की जाँच करना शून्य है, यह जाँचना लगभग समान है ।PasswordChanged झूठा है, इसलिए मैं पसंद करता हूँ lastChangePasswordTime == null सीधे जाँच करें

  2. यहां तर्क बदलते समय, मैं दोनों क्षेत्रों को अपडेट करना भूल सकता हूं ।

नोट: जब कोई उपयोगकर्ता पासवर्ड बदलता है, तो मैं समय को इस तरह रिकॉर्ड करूंगा:

this.lastChangePasswordTime=Date.now();

क्या अतिरिक्त बुलियन क्षेत्र यहां एक अशक्त संदर्भ से बेहतर है?


51
यह सवाल काफी भाषा-विशिष्ट है, क्योंकि एक अच्छा समाधान क्या होता है यह काफी हद तक आपकी प्रोग्रामिंग भाषा प्रदान करता है। उदाहरण के लिए, C ++ 17 या Scala में, आप उपयोग करेंगे std::optionalया Option। अन्य भाषाओं में, आपको स्वयं एक उपयुक्त तंत्र का निर्माण करना पड़ सकता है, या आप वास्तव में nullया कुछ इसी तरह का सहारा ले सकते हैं क्योंकि यह अधिक मुहावरेदार है।
क्रिश्चियन हैक

16
क्या कोई कारण है जो आप चाहते हैं कि lastChangePasswordTime पासवर्ड निर्माण समय पर सेट हो (निर्माण एक मॉड है, आखिरकार)?
क्रिस्टियन एच

@ChristianHackl hmm, इस बात से सहमत हैं कि अलग-अलग "संपूर्ण" समाधान हैं, लेकिन मैं किसी भी (प्रमुख) भाषा को नहीं देखता, हालांकि एक अलग बूलियन का उपयोग करना सामान्य रूप से अशक्त / शून्य जाँच करने से बेहतर विचार होगा। सी / सी ++ के बारे में पूरी तरह से निश्चित नहीं है क्योंकि मैं काफी समय से वहां सक्रिय नहीं हूं, हालांकि।
फ्रैंक हॉपकिन्स

@FrankHopkins: एक उदाहरण ऐसी भाषाएं होंगी, जिनमें चर को बिना किसी खंड के छोड़ दिया जा सकता है, जैसे C या C ++। lastChangePasswordTimeहो सकता है कि वहाँ एक असंक्रमित सूचक हो, और उसकी किसी भी चीज़ से तुलना करना अपरिभाषित व्यवहार होगा। नहीं वास्तव में एक सम्मोहक कारण है कि सूचक को प्रारंभ करने के लिए NULL/ nullptrइसके बजाय, विशेष रूप से आधुनिक सी ++ में नहीं (जहां आप एक सूचक का उपयोग नहीं करेंगे), लेकिन कौन जानता है? एक और उदाहरण संकेत के बिना भाषा होगा, या संकेत के लिए खराब समर्थन के साथ, शायद। (फोरट्रान 77 को ध्यान में आता है ...)
क्रिश्चियन हैकल

मैं इस के लिए 3 मामलों के साथ एक एनुम का उपयोग करूंगा :)
जे डो

जवाबों:


72

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

यदि आपका लक्ष्य गलती से संदर्भित को रोकने के isPasswordChangedलिए अशक्त मान को घेरना है, तो मैं एक फ़ंक्शन या संपत्ति के रूप में मान बनाने का सुझाव दूंगा, जो एक अशक्त चेक का परिणाम लौटाता है, उदाहरण के लिए:

class Member {
    DateTime lastChangePasswordTime = null;
    bool isPasswordChanged() { return lastChangePasswordTime != null; }

}

मेरी राय में, इसे इस तरह से करना:

  • एक अशक्त चेक की तुलना में बेहतर कोड पठनीयता देता है, जो संदर्भ खो सकता है।
  • वास्तव में आपके द्वारा बताए गए isPasswordChangedमूल्य को बनाए रखने के बारे में चिंता करने की आवश्यकता को दूर करता है ।

जिस तरह से आप डेटा को बनाए रखते हैं (संभवतः एक डेटाबेस में) यह सुनिश्चित करने के लिए जिम्मेदार होगा कि नल संरक्षित हैं।


29
उद्घाटन के लिए +1। अशक्त का उपयोग आमतौर पर केवल उन मामलों में अस्वीकृत किया जाता है जहां अशक्त एक अप्रत्याशित परिणाम है, यानी जहां यह (उपभोक्ता के लिए) समझ में नहीं आएगा। यदि अशक्त सार्थक है, तो यह अप्रत्याशित परिणाम नहीं है।
9

28
मैं इसे थोड़ा मजबूत बनाऊंगा क्योंकि कभी भी दो चर नहीं होते जो एक ही अवस्था को बनाए रखते हैं। यह विफल हो जाएगा। एक शून्य मान को छिपाना, शून्य मान को उदाहरण के अंदर समझ में आता है, बाहर से बहुत अच्छी बात है। इस मामले में जहां आप बाद में निर्णय ले सकते हैं कि 1970-01-01 यह बताता है कि पासवर्ड कभी नहीं बदला गया है। फिर बाकी कार्यक्रम के तर्क की परवाह नहीं है।
बेंट

3
आप कॉल करना isPasswordChangedभूल सकते हैं जैसे आप चेक करना भूल सकते हैं कि क्या यह अशक्त है। मुझे यहां कुछ भी हासिल नहीं हुआ।
घुमारवीं

9
@Gherman यदि उपभोक्ता को यह अवधारणा नहीं मिलती है कि अशक्त सार्थक है या उसे वर्तमान मूल्य की जाँच करने की आवश्यकता है, तो वह या तो खो जाता है, लेकिन यदि विधि का उपयोग किया जाता है, तो यह कोड पढ़ने वाले सभी के लिए स्पष्ट है कि वहाँ क्यों एक जाँच है और एक उचित मौका है कि मान शून्य है / मौजूद नहीं है। अन्यथा यह स्पष्ट नहीं है कि यह सिर्फ एक डेवलपर था जो केवल "क्योंकि क्यों नहीं" या यह अवधारणा का हिस्सा है, एक अशक्त जाँच जोड़ रहा है। निश्चित रूप से, कोई भी इसका पता लगा सकता है, लेकिन एक तरीका यह है कि आपके पास सीधे जानकारी है जिसे आपको कार्यान्वयन में देखने की आवश्यकता है।
फ्रैंक हॉपकिन्स

2
@FrankHopkins: अच्छी बात है, लेकिन अगर कंसीडर का इस्तेमाल किया जाता है, तो भी एक ही वेरिएबल के निरीक्षण के लिए लॉकिंग की जरूरत पड़ सकती है।
क्रिश्चियन हैकल

63

nullsबुराई नहीं है। बिना सोचे समझे उनका उपयोग करना है। यह एक ऐसा मामला है जहां nullबिल्कुल सही उत्तर है - कोई तारीख नहीं है।

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

तो नहीं, आपका समाधान बेहतर नहीं है। nullमूल्य के लिए अनुमति देना यहां सही दृष्टिकोण है। जो लोग दावा करते हैं कि nullहमेशा बुराई होती है कोई बात नहीं संदर्भ समझ में क्यों नहीं आता nullहै।


17
ऐतिहासिक रूप से nullमौजूद है , क्योंकि टोनी होरे ने 1965 में अरब-डॉलर की गलती की थी। जो लोग दावा करते हैं कि null"बुराई" विषय को निश्चित रूप से अधिक सरल बना रहे हैं, लेकिन यह अच्छी बात है कि आधुनिक भाषा या प्रोग्रामिंग शैली दूर जा रही हैं null, फिर से बदल रही हैं यह समर्पित विकल्प प्रकारों के साथ है।
क्रिश्चियन हैकल

9
@ChristianHackl: ऐतिहासिक हित से बाहर - होरे कभी कहते हैं कि बेहतर व्यावहारिक विकल्प क्या होगा (पूरी तरह से नए प्रतिमान पर स्विच किए बिना)?
AnoE

5
@AnoE: दिलचस्प सवाल। होरे को उस पर क्या कहना था, इसके बारे में नहीं जानते, लेकिन आधुनिक, अच्छी तरह से डिज़ाइन की गई प्रोग्रामिंग भाषाओं में इन दिनों अशक्त-मुक्त प्रोग्रामिंग अक्सर एक वास्तविकता है।
क्रिश्चियन हैक

10
@ तम वाट? C # और Java जैसी भाषाओं में, DateTimeफ़ील्ड एक पॉइंटर है। केवल संपूर्ण अवधारणा nullही संकेत देने वालों के लिए मायने रखती है!
टोड सेवेल

16
@ टोम: अशक्त संकेत केवल भाषाओं और कार्यान्वयन पर खतरनाक होते हैं जो उन्हें आँख बंद करके अनुक्रमित और निष्क्रिय करने की अनुमति देते हैं, जो भी उल्लंघनों का परिणाम हो सकता है। एक ऐसी भाषा में जो जाल को एक अशक्त सूचक को अनुक्रमित या निष्क्रिय करने का प्रयास करती है, यह अक्सर एक सूचक से एक डमी वस्तु की तुलना में कम खतरनाक होगा। ऐसी कई स्थितियाँ हैं जहाँ प्रोग्राम को असामान्य रूप से समाप्त करना बेहतर हो सकता है, क्योंकि यह अर्थहीन संख्याएँ पैदा करता है, और सिस्टम पर जो उन्हें फँसाते हैं, अशक्त संकेत उसके लिए सही नुस्खा है।
सुपरकैट

29

आपकी प्रोग्रामिंग भाषा के आधार पर, एक optionalडेटा प्रकार जैसे अच्छे विकल्प हो सकते हैं । C ++ (17) में, यह std :: वैकल्पिक होगा । यह या तो अनुपस्थित हो सकता है या अंतर्निहित डेटा प्रकार का एक मनमाना मूल्य हो सकता है।


8
नहीं है Optionalजावा भी में; एक शून्य का अर्थ Optionalआपके ऊपर है ...
मैथ्यू एम।

1
वैकल्पिक के साथ कनेक्ट करने के लिए यहाँ आया था। मैं इसे एक भाषा में एक प्रकार के रूप में सांकेतिक शब्दों में बदलना चाहता हूं जो उनके पास थी।
Zipp

2
@FrankHopkins यह शर्म की बात है कि जावा में कुछ भी आपको लिखने से रोकता है Optional<Date> lastPasswordChangeTime = null;, लेकिन मैं सिर्फ इस वजह से हार नहीं मानूंगा । इसके बजाय, मैं बहुत दृढ़ता से आयोजित टीम नियम को लागू करूंगा, कि किसी भी वैकल्पिक मूल्यों को कभी भी असाइन करने की अनुमति नहीं है null। वैकल्पिक आप आसानी से उस पर छोड़ देने के लिए कई अच्छी सुविधाएँ खरीदता है। आप आसानी से डिफ़ॉल्ट मान असाइन कर सकते हैं ( orElseया आलसी मूल्यांकन के साथ:) orElseGet, त्रुटियां फेंकें ( orElseThrow), मानों को एक सुरक्षित तरीके से रूपांतरित करें ( map, flatmap), आदि
अलेक्जेंडर

5
@FrankHopkins चेक करना isPresentमेरे अनुभव में लगभग हमेशा एक कोड गंध है, और एक बहुत विश्वसनीय संकेत है कि इन वैकल्पिक का उपयोग करने वाले देव "बिंदु को याद कर रहे हैं"। वास्तव में, यह मूल रूप से कोई लाभ नहीं देता है ref == null, लेकिन यह भी कुछ ऐसा नहीं है जिसे आपको अक्सर उपयोग करना चाहिए। भले ही टीम अस्थिर है, एक स्थिर विश्लेषण उपकरण कानून को एक लाइनर या फाइंडबग्स की तरह लेट सकता है , जो कई मामलों को पकड़ सकता है।
अलेक्जेंडर

5
@FrankHopkins: यह हो सकता है कि जावा समुदाय को बस थोड़ा सा बदलाव चाहिए, जिसमें अभी कई साल लग सकते हैं। आप स्काला को देखें, तो उदाहरण के लिए, यह समर्थन करता है, nullक्योंकि भाषा जावा के लिए 100% संगत है, लेकिन कोई भी इसे इस्तेमाल करता है, और Option[T]जगह भर में है, जैसे उत्कृष्ट कार्यात्मक-प्रोग्रामिंग समर्थन के साथ map, flatMap, पैटर्न मिलान और इतने पर है, जो चला जाता है अब तक, दूर से परे == nullजाँच करता है। आप सही हैं कि सिद्धांत रूप में, एक विकल्प प्रकार एक गौरवशाली सूचक की तुलना में थोड़ा अधिक लगता है, लेकिन वास्तविकता उस तर्क को गलत साबित करती है।
क्रिश्चियन हैकल

11

सही ढंग से अशक्त का उपयोग करना

उपयोग करने के विभिन्न तरीके हैं null। सबसे आम और शब्दार्थ रूप से सही तरीका यह है कि आप इसका उपयोग तब करें जब आपके पास एक भी मान हो या न हो । इस मामले में एक मान या तो बराबर होता है nullया डेटाबेस या किसी चीज के रिकॉर्ड की तरह कुछ सार्थक होता है।

इन स्थितियों में आप तब इसे इस तरह से उपयोग करते हैं (छद्म कोड में):

if (value is null) {
  doSomethingAboutIt();
  return;
}

doSomethingUseful(value);

संकट

और इसकी एक बहुत बड़ी समस्या है। समस्या यह है कि जब तक आप doSomethingUsefulमूल्य का आह्वान करते हैं, तब तक की जाँच नहीं की जा सकती है null! यदि ऐसा नहीं होता तो कार्यक्रम दुर्घटनाग्रस्त हो जाता। और उपयोगकर्ता कोई भी अच्छा त्रुटि संदेश भी नहीं देख सकता है, "भयानक त्रुटि: वांछित मूल्य लेकिन शून्य मिला!" (अपडेट के बाद: हालांकि कम सूचनात्मक त्रुटि भी हो सकती है Segmentation fault. Core dumped., जैसे या इससे भी बदतर, कोई त्रुटि नहीं है और कुछ मामलों में अशक्त पर गलत हेरफेर)

स्थितियों को जांचना nullऔर संभालना लिखना nullएक बहुत ही सामान्य बग है । यही कारण है कि आविष्कार करने वाले टोनी होरे nullने 2009 में QCon लंदन नामक एक सॉफ्टवेयर सम्मेलन में कहा था कि उन्होंने 1965 में अरबों डॉलर की गलती की: https://www.infoq.com/pretations/Null-References-The-Billion-Dollar- गलती टोनी-होरे

समस्या से बचना

कुछ प्रौद्योगिकियां और भाषाएं nullअलग-अलग तरीकों से भूलना असंभव की जाँच कर रही हैं, जिससे कीड़े की मात्रा कम हो जाती है।

उदाहरण के लिए हास्केल के पास Maybeनल की बजाय मोनाड है। मान लीजिए कि DatabaseRecordएक उपयोगकर्ता-परिभाषित प्रकार है। हास्केल में प्रकार का मान Maybe DatabaseRecordबराबर Just <somevalue>हो सकता है या इसके बराबर हो सकता है Nothing। फिर आप इसे विभिन्न तरीकों से उपयोग कर सकते हैं, लेकिन कोई फर्क नहीं पड़ता कि आप इसे कैसे उपयोग करते हैं, आप Nothingइसे जानने के बिना कुछ ऑपरेशन को लागू नहीं कर सकते ।

मिसाल के तौर पर इस समारोह कहा जाता zeroAsDefaultरिटर्न xके लिए Just xऔर 0के लिए Nothing:

zeroAsDefault :: Maybe Int -> Int
zeroAsDefault mx = case mx of
    Nothing -> 0
    Just x -> x

क्रिश्चियन हैकल का कहना है कि C ++ 17 और स्काला के अपने तरीके हैं। इसलिए आप यह जानने की कोशिश कर सकते हैं कि आपकी भाषा में ऐसा कुछ है या नहीं और इसका उपयोग करें।

नल अभी भी व्यापक उपयोग में हैं

यदि आपके पास कुछ बेहतर नहीं है तो उपयोग nullकरना ठीक है। बस इसके लिए बाहर देखते रहो। फ़ंक्शंस में टाइप डिक्लेरेशन आपको कुछ भी मदद करेगा।

इसके अलावा, यह बहुत प्रगतिशील नहीं लग सकता है, लेकिन आपको यह देखना चाहिए कि क्या आपके सहकर्मी उपयोग करना चाहते हैं nullया कुछ और। वे रूढ़िवादी हो सकते हैं और कुछ कारणों से नए डेटा संरचनाओं का उपयोग नहीं करना चाह सकते हैं। उदाहरण के लिए किसी भाषा के पुराने संस्करणों का समर्थन करना। ऐसी चीजों को परियोजना के कोडिंग मानकों में घोषित किया जाना चाहिए और टीम के साथ ठीक से चर्चा की जानी चाहिए।

आपके प्रस्ताव पर

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

नल का उपयोग कैसे न करें

अंत में nullगलत तरीके से उपयोग करने के सामान्य तरीके हैं । ऐसा ही एक तरीका खाली डेटा संरचनाओं जैसे सरणियों और तारों के स्थान पर इसका उपयोग करना है। एक खाली सरणी किसी भी अन्य की तरह एक उचित सरणी है! यह डेटा संरचनाओं के लिए लगभग हमेशा महत्वपूर्ण और उपयोगी है, जो कि कई मानों को फिट कर सकता है, खाली होने में सक्षम होने के लिए, अर्थात 0 लंबाई है।

बीजगणित के दृष्टिकोण से स्ट्रिंग के लिए एक खाली स्ट्रिंग संख्याओं के लिए 0 के समान है, अर्थात पहचान:

a+0=a
concat(str, '')=str

खाली स्ट्रिंग सामान्य रूप से स्ट्रिंग्स को एक मोनोड बनने में सक्षम बनाती है: https://en.wikipedia.org/wiki/Monoid यदि आपको यह नहीं मिलता है तो यह आपके लिए उतना महत्वपूर्ण नहीं है।

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

for (element in array) {
  doSomething(element);
}

यदि हम यहां खाली सरणी पास करते हैं तो कोड ठीक काम करेगा। यह सिर्फ कुछ नहीं करेगा। हालाँकि अगर हम nullयहाँ से गुजरते हैं तो हमें "Null, माफ़ नहीं कर सकता" जैसी त्रुटि के साथ एक दुर्घटना होने की संभावना है। हम इसे लपेट सकते हैं, ifलेकिन यह कम साफ है और फिर से, आप इसे जांचना भूल सकते हैं

अशक्त को कैसे संभालें

क्या doSomethingAboutIt()करना चाहिए और विशेष रूप से क्या यह एक अपवाद फेंकना चाहिए एक और जटिल मुद्दा है। संक्षेप में यह इस बात पर निर्भर करता है कि nullकिसी दिए गए कार्य के लिए स्वीकार्य इनपुट मूल्य था या प्रतिक्रिया में क्या अपेक्षित है। अपवाद उन घटनाओं के लिए हैं जो अपेक्षित नहीं थे। मैं उस विषय में आगे नहीं जाऊंगा। यह उत्तर बहुत लंबा है।


5
वास्तव में, horrible error: wanted value but got null!अधिक विशिष्ट से बहुत बेहतर है Segmentation fault. Core dumped....
टोबे स्पीट

2
@TobySpeight सच है, लेकिन मैं कुछ ऐसा पसंद करूँगा जो उपयोगकर्ता की शर्तों के अंदर देता हो Error: the product you want to buy is out of stock
घुमर

ज़रूर - मैं बस देख रहा था कि यह (और अक्सर हो सकता है) भी बदतर है । मैं पूरी तरह से सहमत हूं कि क्या बेहतर होगा! और आपका जवाब बहुत ज्यादा है जो मैंने इस सवाल पर कहा होगा: +1।
टोबी स्पाईट

2
@Gherman: nullजहां nullअनुमति नहीं है वहां पास होना एक प्रोग्रामिंग त्रुटि है, अर्थात कोड में एक बग। स्टॉक से बाहर होने वाला उत्पाद साधारण व्यवसायिक तर्क का हिस्सा है, बग नहीं। आप उपयोगकर्ता इंटरफ़ेस में किसी सामान्य संदेश में बग का पता लगाने का प्रयास नहीं कर सकते, और नहीं करना चाहिए। तुरंत कोडिंग करना और अधिक कोड निष्पादित न करना कार्रवाई का पसंदीदा कोर्स है, खासकर यदि यह एक महत्वपूर्ण एप्लिकेशन है (जैसे कि वास्तविक वित्तीय लेनदेन करता है)।
क्रिश्चियन हैक

1
@EricDuminil हम एक गलती करने की संभावना (या कम) को दूर करना चाहते हैं, न nullकि खुद को पूरी तरह से, यहां तक ​​कि पृष्ठभूमि से भी हटा दें ।
घुमर

4

पहले दिए गए सभी बहुत अच्छे उत्तरों के अलावा, मैं हर बार यह जोड़ना चाहता हूं कि आप किसी क्षेत्र को अशक्त होने के लिए लुभाते हैं, ध्यान से सोचें कि क्या यह एक सूची प्रकार हो सकता है। एक अशक्त प्रकार अनिवार्य रूप से 0 या 1 तत्वों की एक सूची है, और अक्सर इसे एन तत्वों की सूची के लिए सामान्यीकृत किया जा सकता है। विशेष रूप से इस मामले में, आप lastChangePasswordTimeएक सूची होने पर विचार करना चाह सकते हैं passwordChangeTimes


यह एक उत्कृष्ट बिंदु है। विकल्प के प्रकारों के लिए भी यही सच है; एक विकल्प को अनुक्रम के विशेष मामले के रूप में देखा जा सकता है।
क्रिश्चियन हैकल

2

अपने आप से यह पूछें: किस व्यवहार के लिए अंतिम रूप से फ़ील्ड बदलने की आवश्यकता होती है?

यदि आपको विधि के लिए उस फ़ील्ड की आवश्यकता है IsPasswordExpired () यह निर्धारित करने के लिए कि क्या किसी सदस्य को हर बार अपना पासवर्ड बदलने के लिए प्रेरित किया जाना चाहिए, तो मैं उस क्षेत्र को उस समय सेट कर दूंगा जब सदस्य शुरू में बनाया गया था। IsPasswordExpired () कार्यान्वयन नए और मौजूदा सदस्यों के लिए समान है।

class Member{
   private DateTime lastChangePasswordTime;

   public Member(DateTime lastChangePasswordTime) {
      // set value, maybe check for null
   }

   public bool IsPasswordExpired() {
      DateTime limit = DateTime.Now.AddMonths(-3);
      return lastChangePasswordTime < limit;
   }
}

यदि आपके पास एक अलग आवश्यकता है कि नए बनाए गए सदस्यों को अपना पासवर्ड अपडेट करना है, तो मैं एक अलग बूलियन फ़ील्ड जोड़ूंगा, जिसे पासवर्डशोल्डबैंचिंग कहा जाएगा और यह निर्माण पर सही होगा। मैं तब उस फ़ील्ड के लिए एक चेक शामिल करने के लिए IsPasswordExpired () विधि की कार्यक्षमता को बदल दूंगा (और विधि का नाम बदलकर ShouldChangePassword) कर दूंगा।

class Member{
   private DateTime lastChangePasswordTime;
   private bool passwordShouldBeChanged;

   public Member(DateTime lastChangePasswordTime, bool passwordShouldBeChanged) {
      // set values, maybe check for nulls
   }

   public bool ShouldChangePassword() {
      return PasswordExpired(lastChangePasswordTime) || passwordShouldBeChanged;
   }

   private static bool PasswordExpired(DateTime lastChangePasswordTime) {
      DateTime limit = DateTime.Now.AddMonths(-3);
      return lastChangePasswordTime < limit;
   }
}

कोड में अपने इरादे स्पष्ट करें।


2

सबसे पहले, अशक्त होना बुराई है और हठधर्मिता के साथ हमेशा की तरह यह एक दिशानिर्देश के रूप में सबसे अच्छा काम करता है और पास / नो पास टेस्ट के रूप में नहीं।

दूसरे, आप अपनी स्थिति को इस तरह से फिर से परिभाषित कर सकते हैं कि यह समझ में आता है कि मूल्य कभी भी शून्य नहीं हो सकता है। InititialPasswordChanged एक बूलियन है जो शुरू में गलत पर सेट किया गया था, जब पासवर्ड चालू किया गया था, तो PasswordSetTime तारीख और समय है।

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


1

यदि उपयोग करने से पहले कॉलर चेक करता है तो दोनों 'सुरक्षित / सुरक्षित / सही' हैं। समस्या यह है कि क्या होता है यदि कॉल करने वाला जाँच नहीं करता है। जो बेहतर है, अशक्त त्रुटि का कुछ स्वाद या अमान्य मूल्य का उपयोग कर रहा है?

एक भी सही उत्तर नहीं है। यह इस बात पर निर्भर करता है कि आप किस बारे में चिंतित हैं।

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

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.