कंस्ट्रक्टर में बसने वालों का उपयोग करना एक सामान्य पैटर्न क्यों नहीं बन गया?


23

Accessors और modifiers (उर्फ सेटर और गेटर्स) तीन मुख्य कारणों के लिए उपयोगी हैं:

  1. वे चर तक पहुंच को प्रतिबंधित करते हैं।
    • उदाहरण के लिए, एक चर को एक्सेस किया जा सकता है, लेकिन संशोधित नहीं।
  2. वे मापदंडों को मान्य करते हैं।
  3. वे कुछ दुष्प्रभाव पैदा कर सकते हैं।

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

public class Cat {
    private int age;

    public int getAge() {
        return this.age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

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

/**
 * Sets the age for the current cat
 * @param age an integer with the valid values between 0 and 25
 * @return true if value has been assigned and false if the parameter is invalid
 */
public boolean setAge(int age) {
    //Validate your parameters, valid age for a cat is between 0 and 25 years
    if(age > 0 && age < 25) {
        this.age = age;
        return true;
    }
    return false;
}

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

public class Cat {
    private int age;

    public Cat(int age) {
        this.age = age;
    }

    public int getAge() {
        return this.age;
    }

    /**
     * Sets the age for the current cat
     * @param age an integer with the valid values between 0 and 25
     * @return true if value has been assigned and false if the parameter is invalid
     */
    public boolean setAge(int age) {
        //Validate your parameters, valid age for a cat is between 0 and 25 years
        if(age > 0 && age < 25) {
            this.age = age;
            return true;
        }
        return false;
    }

}

लेकिन कोई यह सोचेगा कि यह दूसरा तरीका बहुत सुरक्षित है:

public class Cat {
    private int age;

    public Cat(int age) {
        //Use the modifier instead of assigning the value directly.
        setAge(age);
    }

    public int getAge() {
        return this.age;
    }

    /**
     * Sets the age for the current cat
     * @param age an integer with the valid values between 0 and 25
     * @return true if value has been assigned and false if the parameter is invalid
     */
    public boolean setAge(int age) {
        //Validate your parameters, valid age for a cat is between 0 and 25 years
        if(age > 0 && age < 25) {
            this.age = age;
            return true;
        }
        return false;
    }

}

क्या आप अपने अनुभव में एक समान पैटर्न देखते हैं या यह सिर्फ मेरे लिए अशुभ है? और अगर आप करते हैं, तो आपको क्या लगता है कि क्या कारण है? क्या कंस्ट्रक्टरों से संशोधक का उपयोग करने के लिए एक स्पष्ट नुकसान है या क्या उन्हें सिर्फ सुरक्षित माना जाता है? यह कुछ और है?


1
@stg, शुक्रिया, दिलचस्प बात! क्या आप इस पर विस्तार कर सकते हैं और इसे एक बुरी चीज़ के उदाहरण के साथ उत्तर में डाल सकते हैं जो शायद होगा?
व्लाद स्प्रीज़


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

1
@gnat: मुझे विश्वास नहीं है कि क्या यह एक वर्ग के तरीकों को अपने स्वयं के गेटर्स और बसने वालों की नकल करना चाहिए? , क्योंकि रचनाकार कॉल की प्रकृति को पूरी तरह से नहीं बनने वाली वस्तु पर कॉल किया जाता है।
ग्रेग बरगार्ड

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

जवाबों:


37

बहुत सामान्य दार्शनिक तर्क

आमतौर पर, हम पूछते हैं कि एक कंस्ट्रक्टर निर्माण की स्थिति के बारे में कुछ गारंटी देता है (पोस्ट-शर्तों के रूप में)।

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

कंस्ट्रक्टर के अंदर से इंस्टेंस मेथड को कॉल करने का मतलब है कि कुछ या सभी गारंटियां अभी तक स्थापित नहीं की गई हैं, जो इस बात की वजह से मुश्किल है कि इंस्टेंस मेथड की पूर्व-शर्तें पूरी हो गई हैं या नहीं। यहां तक ​​कि अगर आप इसे सही कर लेते हैं, तो उदाहरण के लिए, यह बहुत नाजुक हो सकता है। इंस्टेंस का री-ऑर्डर करने का तरीका कॉल या अन्य ऑपरेशन करता है।

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

विशिष्ट उदाहरण

  1. आपके विचार से यह कैसे दिखना चाहिए, इसका अपना उदाहरण स्वयं गलत है:

    public Cat(int age) {
        //Use the modifier instead of assigning the value directly.
        setAge(age);
    }

    इससे वापसी मान की जाँच नहीं होती है setAge। जाहिरा तौर पर सेटर को फोन करना सब के बाद शुद्धता की कोई गारंटी नहीं है।

  2. आरंभीकरण क्रम के आधार पर बहुत आसान गलतियाँ, जैसे:

    class Cat {
      private Logger m_log;
      private int m_age;
    
      public void setAge(int age) {
        // FIXME temporary debug logging
        m_log.write("=== DEBUG: setting age ===");
        m_age = age;
      }
    
      public Cat(int age, Logger log) {
        setAge(age);
        m_log = log;
      }
    };

    जहां मेरे अस्थायी लॉगिंग ने सब कुछ तोड़ दिया। ओह!

सी ++ जैसी भाषाएं भी हैं, जहां कंस्ट्रक्टर से एक सेटर को कॉल करने का अर्थ है एक व्यर्थ डिफ़ॉल्ट आरंभीकरण (जो कुछ सदस्य चर के लिए कम से कम टालने लायक है)

एक साधारण प्रस्ताव

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

class Cat {
  private int m_age;
  private static void checkAge(int age) {
    if (age > 25) throw CatTooOldError(age);
  }

  public void setAge(int age) {
    checkAge(age);
    m_age = age;
  }

  public Cat(int age) {
    checkAge(age);
    m_age = age;
  }
};

या इससे भी बेहतर, यदि संभव हो तो: संपत्ति प्रकार में बाधा को सांकेतिक शब्दों में बदलना, और यह असाइनमेंट पर अपने स्वयं के मूल्य को मान्य करता है:

class Cat {
  private Constrained<int, 25> m_age;

  public void setAge(int age) {
    m_age = age;
  }

  public Cat(int age) {
    m_age = age;
  }
};

और अंत में, पूर्णता के लिए, C ++ में एक स्व-वैध आवरण। ध्यान दें कि हालांकि यह अभी भी थकाऊ सत्यापन कर रहा है, क्योंकि यह वर्ग और कुछ नहीं करता है , यह जांचना अपेक्षाकृत आसान है

template <typename T, T MAX, T MIN=T{}>
class Constrained {
    T val_;
    static T validate(T v) {
        if (MIN <= v && v <= MAX) return v;
        throw std::runtime_error("oops");
    }
public:
    Constrained() : val_(MIN) {}
    explicit Constrained(T v) : val_(validate(v)) {}

    Constrained& operator= (T v) { val_ = validate(v); return *this; }
    operator T() { return val_; }
};

ठीक है, यह वास्तव में पूरा नहीं हुआ है, मैंने विभिन्न कॉपी और बिल्डरों और असाइनमेंट को छोड़ दिया है।


4
भारी-भरकम जवाब नहीं! मुझे केवल इसलिए जोड़ते हैं क्योंकि ओपी ने पाठ्य पुस्तक में वर्णित स्थिति को देखा है, यह एक अच्छा समाधान नहीं है। यदि एक विशेषता (कंस्ट्रक्टर और सेटर द्वारा) सेट करने के लिए कक्षा में दो तरीके हैं, और एक उस विशेषता पर एक बाधा को लागू करना चाहता है, तो सभी तरीकों से बाधा की जांच करनी चाहिए, अन्यथा यह एक डिज़ाइन बग है
Doc Brown

तो क्या आप एक विधायक के बुरे व्यवहार में सेटर के तरीकों का उपयोग करने पर विचार करेंगे यदि बसने वालों में कोई तर्क नहीं है, या 2) बसने वालों में तर्क राज्य से स्वतंत्र है? मैं इसे अक्सर नहीं करता हूं, लेकिन मैंने व्यक्तिगत रूप से एक विधायक में सेटर विधियों का उपयोग बाद के कारण के लिए किया है (जब सेटर में कुछ प्रकार की स्थिति होती है जो हमेशा सदस्य चर पर लागू होनी चाहिए
क्रिस मैगुल्ली

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

13

जब एक वस्तु का निर्माण किया जा रहा है, तो यह परिभाषा के अनुसार पूरी तरह से नहीं है। विचार करें कि आपके द्वारा प्रदान किया गया सेटर कैसा है:

public boolean setAge(int age) {
    //Validate your parameters, valid age for a cat is between 0 and 25 years
    if(age > 0 && age < 25) {
        this.age = age;
        return true;
    }
    return false;
}

क्या होगा अगर सत्यापन का हिस्सा संपत्ति के setAge()खिलाफ एक जांच में यह ageसुनिश्चित करने के लिए शामिल हो कि वस्तु केवल उम्र में बढ़ सकती है? वह स्थिति इस तरह दिख सकती है:

if (age > this.age && age < 25) {
    //...

यह एक बहुत ही निर्दोष परिवर्तन की तरह लगता है, क्योंकि बिल्लियां केवल एक दिशा में समय के माध्यम से आगे बढ़ सकती हैं। एकमात्र समस्या यह है कि आप इसका उपयोग प्रारंभिक मूल्य निर्धारित करने के लिए नहीं कर सकते this.ageक्योंकि यह मानता है कि this.ageपहले से ही एक वैध मूल्य है।

कंस्ट्रक्टर्स में बसने से बचना यह स्पष्ट करता है कि कंस्ट्रक्टर केवल एक ही चीज कर रहा है, उदाहरण चर को सेट कर रहा है और सेटर में होने वाले किसी भी अन्य व्यवहार को छोड़ देता है।


ठीक है ... लेकिन, यदि आप वास्तव में ऑब्जेक्ट निर्माण का परीक्षण नहीं करते हैं और संभावित बगों को उजागर करते हैं, तो संभावित कीड़े हैं । और अब आपको दो दो समस्याएँ मिल गई हैं : आपके पास वह छिपी हुई संभावित बग है और आपको दो स्थानों पर आयु-सीमा की जाँच को लागू करना होगा।
svidgen

कोई समस्या नहीं है, जैसा कि जावा / सी # में सभी फ़ील्ड निर्माता-मंगलाचरण से पहले शून्य हैं।
डेडुप्लिकेटर

2
हां, कंस्ट्रक्टरों से कॉलिंग के तरीकों के बारे में तर्क करना मुश्किल हो सकता है और आमतौर पर पसंद नहीं किया जाता है। अब, यदि आप अपने सत्यापन तर्क को एक निजी, अंतिम कक्षा / स्थैतिक विधि में स्थानांतरित करना चाहते हैं, और इसे कंस्ट्रक्टर और सेटर दोनों से कहते हैं, तो यह ठीक होगा।
बेकार

1
नहीं, गैर-इंस्टेंस विधियाँ इंस्टेंस विधियों की चालाकी से बचती हैं, क्योंकि वे आंशिक रूप से निर्मित उदाहरण को नहीं छूती हैं। बेशक, आपको यह तय करने की आवश्यकता है कि निर्माण सफल हुआ या नहीं।
बेकार

1
यह उत्तर IMHO बिंदु को याद कर रहा है। "जब एक वस्तु का निर्माण किया जा रहा है, तो यह पूरी तरह से नहीं बनाई गई परिभाषा के अनुसार है" - निर्माण प्रक्रिया के बीच में, निश्चित रूप से, लेकिन जब निर्माण किया जाता है, तो विशेषताओं पर किसी भी इरादा बाधाएं पकड़नी चाहिए, अन्यथा कोई भी उस बाधा को दरकिनार कर सकता है। मुझे लगता है कि एक गंभीर डिजाइन दोष होगा।
Doc Brown

6

यहाँ पहले से ही कुछ अच्छे उत्तर हैं, लेकिन अभी तक किसी ने भी नहीं देखा था कि आप यहाँ दो चीजों को एक में पूछ रहे हैं, जिससे कुछ भ्रम होता है। IMHO आपकी पोस्ट को दो अलग-अलग प्रश्नों के रूप में देखा जाता है :

  1. यदि किसी सेटर में अड़चन की मान्यता है, तो क्या यह सुनिश्चित करने के लिए वर्ग के कंस्ट्रक्टर में भी नहीं होना चाहिए कि यह बाईपास नहीं किया जा सकता है?

  2. निर्माणकर्ता से इस उद्देश्य के लिए सीधे सेटर को क्यों नहीं बुलाया गया?

पहले प्रश्नों का उत्तर स्पष्ट रूप से "हां" है। एक रचनाकार, जब वह अपवाद नहीं फेंकता है, तो उसे एक वैध स्थिति में वस्तु को छोड़ देना चाहिए, और यदि कुछ विशेषताओं के लिए कुछ मान निषिद्ध हैं, तो यह पूरी तरह से समझ में नहीं आता है कि ctor इसको दरकिनार कर दे।

हालाँकि, दूसरे प्रश्न का उत्तर आम तौर पर "नहीं" है, जब तक आप किसी व्युत्पन्न वर्ग में सेटर को ओवरराइड करने से बचने के लिए उपाय नहीं करते हैं। इसलिए, बेहतर विकल्प एक निजी पद्धति में बाधा सत्यापन को लागू करना है, जिसे सेटर के साथ-साथ कंस्ट्रक्टर से भी पुन: उपयोग किया जा सकता है। मैं यहाँ @Useless उदाहरण दोहराने नहीं जा रहा हूँ, जो बिल्कुल इस डिज़ाइन को दर्शाता है।


मुझे अभी भी समझ में नहीं आया कि सेटर से तर्क निकालना बेहतर क्यों है ताकि कंस्ट्रक्टर इसका इस्तेमाल कर सके। ... यह वास्तव में एक वाजिब क्रम में बसने वालों को कॉल करने से अलग कैसे है ?? विशेष रूप से यह देखते हुए कि, यदि आपके निवासी उतने ही सरल हैं जितना कि उन्हें "होना चाहिए", सेटर का एकमात्र हिस्सा आपके निर्माता, इस बिंदु पर, आह्वान नहीं कर रहा है, अंतर्निहित क्षेत्र की वास्तविक सेटिंग है ...
svidgen

2
@svidgen: जिमीजैम्स उदाहरण देखें: संक्षेप में, यह एक अच्छा विचार नहीं है कि एक ctor में overridable Methods का उपयोग करें, जिससे समस्याएँ उत्पन्न होंगी। यदि अंतिम है और आप किसी अन्य ओवररिडबल तरीकों को नहीं कहते हैं तो आप सेटर में सेटर का उपयोग कर सकते हैं। इसके अलावा, जब यह विफल हो जाता है तो इसे संभालने के तरीके से मान्यता को अलग करना आपको इसे ctor और सेटर में अलग तरीके से संभालने का अवसर प्रदान करता है।
डॉक ब्राउन

खैर, मैं अब भी कम आश्वस्त हूं! लेकिन, मुझे दूसरे जवाब की ओर इशारा करने के लिए धन्यवाद ...
22

2
द्वारा एक उचित क्रम में तुम्हारा मतलब एक भंगुर साथ, अदृश्य आदेश निर्भरता आसानी से मासूम दिखने परिवर्तन से टूट , है ना?
बेकार

@ अच्छी तरह से, नहीं ... मेरा मतलब है, यह मजेदार है कि आप उस आदेश का सुझाव देंगे जिसमें आपका कोड निष्पादित नहीं होना चाहिए। लेकिन, यह वास्तव में बात नहीं थी। बात सुराग की इस प्रकार की - काल्पनिक उदाहरण के अलावा, मैं तो बस मेरे अनुभव में एक उदाहरण मैं कहाँ सोचा है यह एक अच्छा विचार था एक सेटर में पार संपत्ति सत्यापन के लिए याद नहीं आ रहा जरूरी "अदृश्य" मंगलाचरण से आदेश की आवश्यकताओं के । फिर चाहे
वो

2

यहाँ जावा कोड का एक मूर्खतापूर्ण हिस्सा है जो आपके निर्माता में गैर-अंतिम तरीकों का उपयोग करके आपके द्वारा चलाए जा सकने वाले मुद्दों को प्रदर्शित करता है:

import java.util.regex.Pattern;

public class Problem
{
  public static final void main(String... args)
  {
    Problem problem = new Problem("John Smith");
    Problem next = new NextProblem("John Smith", " ");

    System.out.println(problem.getName());
    System.out.println(next.getName());
  }

  private String name;

  Problem(String name)
  {
    setName(name);
  }

  void setName(String name)
  {
    this.name = name;
  }

  String getName()
  {
    return name;
  }
}

class NextProblem extends Problem
{
  private String firstName;
  private String lastName;
  private final String delimiter;

  NextProblem(String name, String delimiter)
  {
    super(name);

    this.delimiter = delimiter;
  }

  void setName(String name)
  {
    String[] parts = name.split(Pattern.quote(delimiter));

    this.firstName = parts[0];
    this.lastName = parts[1];
  }

  String getName()
  {
    return firstName + " " + lastName;
  }
}

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

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

किसी भी घटना में, सत्यापन या अन्य तर्क का पुन: उपयोग करना एक अच्छा लक्ष्य है और आप इसे एक स्थिर विधि में डाल सकते हैं और इसे निर्माता और सेटर दोनों से प्राप्त कर सकते हैं।


यह कैसे खराब कार्यान्वित विरासत की समस्या के बजाय निर्माणकर्ता में बसने का उपयोग करने की समस्या है ??? दूसरे शब्दों में, यदि आप बेस कंस्ट्रक्टर को प्रभावी रूप से अमान्य कर रहे हैं, तो आप इसे कॉल क्यों करेंगे!
22

1
मुझे लगता है कि बिंदु एक सेटर को ओवरराइड कर रहा है, उसे कंस्ट्रक्टर को अमान्य नहीं करना चाहिए।
क्रिस वोहलर्ट

@ क्रिस वॉल्हर्ट ओके ... लेकिन, यदि आप अपने सेटर लॉजिक को अपने कंस्ट्रक्टर लॉजिक के साथ संघर्ष में बदलते हैं, तो यह समस्या है कि आपका कंस्ट्रक्टर सेटर का उपयोग करता है या नहीं। या तो यह निर्माण के समय में विफल रहता है, यह बाद में विफल हो जाता है, या यह अदृश्य रूप से विफल होता है (b / c जिसे आपने अपने व्यावसायिक नियमों को दरकिनार कर दिया है)।
svidgen

आप अक्सर नहीं जानते हैं कि बेस-क्लास का कंस्ट्रक्टर कैसे लागू किया जाता है (यह कहीं 3 पार्टी लाइब्रेरी में हो सकता है)। ओवरराइड करने योग्य विधि को ओवरराइड करने से आधार-कार्यान्वयन का अनुबंध नहीं टूटना चाहिए, (और यकीनन यह उदाहरण nameक्षेत्र को स्थापित नहीं करके ऐसा करता है )।
हल्क

@svidgen यहाँ समस्या यह है कि निर्माणकर्ता से अधिक उपयोग करने योग्य तरीकों को कॉल करने से उन्हें ओवरराइड करने की उपयोगिता कम हो जाती है - आप ओवरराइड किए गए संस्करणों में चाइल्ड क्लास के किसी भी क्षेत्र का उपयोग नहीं कर सकते क्योंकि वे अभी तक आरंभीकृत नहीं किए जा सकते हैं। क्या बुरा है, आपको thisकिसी अन्य विधि के लिए -reference पास नहीं करना चाहिए , क्योंकि आप सुनिश्चित नहीं कर सकते हैं कि यह अभी तक पूरी तरह से आरंभिक है।
हल्क

1

निर्भर करता है!

यदि आप साधारण सत्यापन कर रहे हैं या संपत्ति में सेट होने पर हर बार हिट होने की जरूरत है , तो सेटर का उपयोग करें : सेटर का उपयोग करें। विकल्प आमतौर पर सेटर सेटर लॉजिक को निकालने के लिए होता है और सेटर और कंस्ट्रक्टर दोनों से वास्तविक सेट द्वारा पीछा की गई नई विधि को लागू करता है - जो प्रभावी रूप से सेटर का उपयोग करने के समान है! (अभी छोड़कर आप दो जगहों पर अपना, समान रूप से छोटा, दो-लाइन सेटर बनाए रख रहे हैं।)

हालाँकि , यदि आपको किसी विशेष सेटर (या दो!) को सफलतापूर्वक निष्पादित करने से पहले ऑब्जेक्ट को व्यवस्थित करने के लिए जटिल ऑपरेशन करने की आवश्यकता है , तो सेटर का उपयोग न करें।

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


मैं भी जोड़ूंगा, अगर मेरी याददाश्त दूर से भी ठीक है, तो यह तर्क मुझे कॉलेज में भी पढ़ाया जाता है। और, यह उन सभी सफल परियोजनाओं के अनुरूप नहीं है, जिन पर काम करने के लिए मेरे पास प्रिवी थी।

अगर मुझे अनुमान लगाना था, तो मैंने कुछ बिंदु पर एक "क्लीन कोड" ज्ञापन को याद किया, जिसमें कुछ विशिष्ट बग की पहचान की गई, जो एक कंस्ट्रक्टर में बसने वालों का उपयोग करने से उत्पन्न हो सकते हैं। लेकिन, मेरे हिस्से के लिए, मैं ऐसे किसी भी कीड़े का शिकार नहीं हुआ ...

इसलिए, मेरा तर्क है कि इस विशेष निर्णय को व्यापक और हठधर्मी होने की आवश्यकता नहीं है।

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