2012-09-07 22 views
21

यदि मेरे पास एक ओवरलोडेड कन्स्ट्रक्टर (डिफ़ॉल्ट और पैरा के साथ एक) वाला ग्राहक वर्ग है तो अधिभारित कन्स्ट्रक्टर में कक्षा के सदस्यों को सेट करने का उचित तरीका क्या है? "इस" संदर्भों का उपयोग या सेटटर विधियों का उपयोग कर?कक्षा सर्वोत्तम अभ्यास

बस यह सुनिश्चित नहीं था कि उचित विधि क्या थी।

public class Customer { 

private String firstName; 
private String lastName; 
private int age; 

public Customer() {} 

//This Way 
public Customer(String firstName, String lastName, int age) 
{ 
    this.firstName = firstName; 
    this.lastName = lastName; 
    this.age = age; 
} 

// Or this way? 
    public Customer(String firstName, String lastName, int age) 
{ 
    setFirstName(firstName); 
    setLastName(lastName); 
    setAge(age); 
} 



/** 
* @return the firstName 
*/ 
public String getFirstName() { 
    return firstName; 
} 

/** 
* @param firstName the firstName to set 
*/ 
public void setFirstName(String firstName) { 
    this.firstName = firstName; 
} 

/** 
* @return the lastName 
*/ 
public String getLastName() { 
    return lastName; 
} 

/** 
* @param lastName the lastName to set 
*/ 
public void setLastName(String lastName) { 
    this.lastName = lastName; 
} 

/** 
* @return the age 
*/ 
public int getAge() { 
    return age; 
} 

/** 
* @param age the age to set 
*/ 
public void setAge(int age) { 
    this.age = age; 
} 

}

उत्तर

27

पहला वाला (this. का उपयोग करना) शायद सुरक्षित और अधिक सरल है। इस बात पर विचार करें कि भविष्य में सबक्लास सेटटर विधियों को ओवरराइड करता है - इससे बहुत अप्रत्याशित व्यवहार हो सकता है।

यदि आपकी कक्षा अंतिम है, तो यह अप्रासंगिक है और यह धो है।

+4

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

+0

@ कुमरविवेक मित्रा - मुझे आपका जवाब पसंद नहीं है, क्योंकि मेरी टिप्पणी यह ​​इंगित करती है। –

+0

@TedHopp कृपया मेरा जवाब दोबारा पढ़ें ... मुझे लगता है कि हम दोनों एक ही बात पर बात कर रहे हैं ..... फिर भी मुझे इसे फिर से लिखने दो ... मुझे लगता है कि आप 'ओसीपी' सिद्धांत ले रहे हैं, कक्षाएं विस्तार के लिए खुली हैं, लेकिन संशोधन के लिए बंद हैं .... और जैसा कि मुझे पता है कि रचनाकारों को विरासत में नहीं मिला है, और इसलिए ओवरराइड नहीं किया जा सकता है, इसलिए इसका अपरिवर्तनीय .... ' –

0

मूल रूप से, वहाँ सत्यापन के अलावा कोई अंतर नहीं है।

एक तरफ, यदि आपका सेटर केवल नए मानों (वे ऑब्जेक्ट स्थिति पर निर्भर नहीं है) के आधार पर नए मानों को मान्य करता है, तो सेटर को सत्यापन तर्क को डुप्लिकेट करने से बचा जाता है।

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

0

सीधी पहुंच का रास्ता तेज़ है (अगर स्मृति मुझे सही तरीके से सेवा करता है तो 7 गुना तेज) लेकिन दूसरा मूल्य उन मूल्यों को असाइन करने या असाइनमेंट की श्रृंखला को निर्दिष्ट करने के लिए "सुरक्षित" है (जहां आप दूसरे क्षेत्र को असाइन करते हैं दूसरे का सेटटर) जहां एक्सेसर्स में कार्यान्वित किया गया है, यह तब तक है जब तक कि आप निश्चित रूप से उन नियमों/श्रृंखलाओं को बाईपास नहीं करना चाहते हैं जब असाइनमेंट कन्स्ट्रक्टर से किया जाता है।

तो संक्षेप में, यह आपकी आवश्यकताओं पर निर्भर करता है लेकिन वे मुख्य चिंताएं हैं जिनके बारे में मैं सोच सकता हूं।

+0

की जानकारी की सराहना करता हूं दूसरी विधि "सुरक्षित" से बहुत दूर है जब तक कि सेटटर विधियां (या कक्षा) 'अंतिम' न हों। क्या होगा अगर उप-वर्ग सेटटर को ओवरराइड करता है और सुपरक्लास तक कॉल करने में विफल रहता है? –

+1

यदि आप किसी प्रकार को उप-वर्गीकृत कर रहे हैं और उनके साथ कुछ भी सेट किए बिना सेटर विधियों को ओवरराइड कर रहे हैं तो आपको किस कन्स्ट्रक्टर का उपयोग करने का निर्णय लेने से बहुत बड़ी समस्या मिली है। –

+0

@ टेडहोप मैं जॉर्डन व्हाइट ने जो कहा था उसका एक लंबा विवरण लिख रहा था इसलिए मैं इसे छोड़ दूंगा :) – JTMon

1

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

2

इसकी नहीं है जिसके बारे में यह करने के लिए एक बेहतर तरीका है, लेकिन क्या आप इससे बाहर चाहते हैं ......

- आप अपने वर्ग mutable हो सकता है, तो setters के साथ जाना चाहते हैं।

- आप अपने वर्ग Immutable होना चाहते हैं तो मुझे लगता है कि this का उपयोग कर, एक बेहतर विकल्प है।

मुझे लगता है कि this का उपयोग करना, स्थानों में उपयुक्त है, जहां आपको वेबसर्वर या कुछ स्रोत से कुछ डेटा प्राप्त होता है, फिर उन्हें एक कस्टम क्लास के उदाहरणों के रूप में संग्रह में संग्रहीत करें .....

उदाहरण के लिए:

  • एक कक्षा के छात्र बनाएँ,

  • आप उदाहरण के लिए, कुछ वेब सेवा के लिए एक अनुरोध है, तो आप प्रतिक्रिया मिल जाएगा बनाने के रूप में:JSON ..

  • इसे पार्स करें, फिर छात्र का एक इंस्टेंस बनाएं और इसे संग्रह में संग्रहीत करें ..

    जैसे:

    ArrayList<Student> arList = new ArrayList<Student>();

    arList.add(new Student(name,rollNos,class,marks));

+0

एक कन्स्ट्रक्टर से एक गैर-अंतिम विधि (जैसे एक सेटटर) को कॉल करना एक अच्छा विचार नहीं है। देखें, उदाहरण के लिए, [यह आलेख] (http://www.informit.com/articles/article.aspx?p=20521)। –

+0

@TedHopp मुझे लगता है कि आप 'ओसीपी' सिद्धांत ले रहे हैं, कक्षाएं विस्तार के लिए खुली हैं, लेकिन संशोधन के लिए बंद हैं .... और जैसा कि मुझे पता है कि रचनाकारों को विरासत में नहीं मिला है, और इसलिए इसे अपरिवर्तित नहीं किया जा सकता है, इसलिए यह अपरिवर्तनीय है। ... ' –

+0

देखें [यह] (https://www.securecoding.cert.org/confluence/display/java/MET05-J.+Ensure+that+constructors+do+not+call+overridable+methods) के लिए एक कन्स्ट्रक्टर से किसी को ओवरराइड करने योग्य विधि क्यों नहीं बुलाए जाने का एक अच्छा स्पष्टीकरण। अधिकांश लिंट उपकरण कन्स्ट्रक्टर से सेटर विधियों को कॉल करने के बारे में शिकायत करेंगे (जब तक कि विधि या कक्षा अंतिम न हो, या विधि निजी है - इस मामले में विधि को ओवरराइड नहीं किया जा सकता है)। –

0

जैसा कि पहले ही यह काफी निर्माता में overridable तरीकों कॉल करने के लिए खतरनाक है कहा गया था। हालांकि अगर आपको सेटटर में होने वाली किसी प्रकार की सत्यापन करने की आवश्यकता है तो आपके पास अभी भी इसे प्राप्त करने के कुछ समझदार तरीके हैं।

  1. सेटर अंतिम बनाएं। सबसे तेज़ समाधान यह पहले से ही कहा गया है लेकिन यह एकमात्र विकल्प नहीं है।
  2. सेटर की निजी प्रति का उपयोग करें।
  3. कन्स्ट्रक्टर के बजाय फैक्टरी विधि का उपयोग करें। मैं आमतौर पर इस के साथ चिपक जाता हूं। क्योंकि अगर सत्यापन विफल हो जाता है तो इस स्थिति को संभालने के लिए आपको अधिक स्वतंत्रता मिलती है और यह इरादे से बेहतर (2)
संबंधित मुद्दे