मैंने जोश के लिए जो बनाया है, वह जोश बलोच के बिल्डर पैटर्न पर एक बड़ा सुधार है। किसी भी तरह से यह कहने के लिए नहीं कि यह "बेहतर" है, बस एक बहुत ही विशिष्ट स्थिति में , यह कुछ फायदे प्रदान करता है - सबसे बड़ा यह है कि यह बिल्डर को अपने-से-निर्मित वर्ग से डिकम्पोज करता है।
मैंने नीचे इस विकल्प को अच्छी तरह से प्रलेखित किया है, जिसे मैं ब्लाइंड बिल्डर पैटर्न कहता हूं।
डिजाइन पैटर्न: ब्लाइंड बिल्डर
जोशुआ बलोच के बिल्डर पैटर्न (प्रभावी जावा, 2 संस्करण में आइटम 2) के विकल्प के रूप में, मैंने "ब्लाइंड बिल्डर पैटर्न" को कॉल किया है, जो बलोच बिल्डर के कई लाभों को साझा करता है और, एक ही चरित्र से अलग होता है। बिल्कुल उसी तरह से उपयोग किया जाता है। ब्लाइंड बिल्डर्स का फायदा है
- बिल्डर को उसके संलग्न वर्ग से अलग करना, एक परिपत्र निर्भरता को समाप्त करना,
- एनक्लोजिंग क्लास, और (जो अब नहीं है ) के स्रोत कोड के आकार को बहुत कम कर देता है
- अपने बिल्डर का विस्तार किए बिना
ToBeBuilt वर्ग को विस्तारित करने की अनुमति देता है ।
इस दस्तावेज़ीकरण में, मैं क्लास " ToBeBuilt" क्लास के रूप में निर्मित होने का उल्लेख करूँगा ।
बलोच बिल्डर के साथ एक वर्ग लागू किया गया
एक बलोच बिल्डर public static classउस वर्ग के अंदर निहित होता है जिसे वह बनाता है। एक उदाहरण:
सार्वजनिक वर्ग UserConfig {
निजी अंतिम स्ट्रिंग sName;
निजी अंतिम int iAge;
निजी अंतिम स्ट्रिंग sFavColor;
सार्वजनिक उपयोगकर्ताकॉन्फ़िग (UserConfig.Cfg uc_c) {// CONSTRUCTOR
// स्थानांतरण
प्रयत्न {
sName = uc_c.sName;
} पकड़ (NullPointerException rx) {
नई NullPointerException ("uc_c") फेंकें;
}
iAge = uc_c.iAge;
sFavColor = uc_c.sFavColor;
/ / यहां सभी फील्ड्स मान्य करें
}
सार्वजनिक स्ट्रिंग toString () {
वापसी "नाम =" + sName + ", आयु =" + iAge + ", sFavColor =" + sFavColor;
}
//builder...START
सार्वजनिक स्थिर वर्ग Cfg {
निजी स्ट्रिंग sName;
निजी int iAge;
निजी स्ट्रिंग sFavColor;
सार्वजनिक Cfg (स्ट्रिंग s_name) {
sName = s_name;
}
// सेल्फ-रिटर्निंग सेटर ... START
सार्वजनिक Cfg आयु (int i_age) {
iAge = i_age;
इसे वापस करो;
}
सार्वजनिक Cfg पसंदीदाColor (स्ट्रिंग s_color) {
sFavColor = s_color;
इसे वापस करो;
}
// सेल्फ-रिटर्निंग सेटर ... END
सार्वजनिक UserConfig बिल्ड () {
वापसी (नया यूजर कॉनफिग (यह));
}
}
//builder...END
}
बलोच बिल्डर के साथ एक क्लास को इंस्टेंट करना
UserConfig uc = new UserConfig.Cfg ("Kermit")। आयु (50) .favoriteColor ("हरा")। Build ();
वही वर्ग, जिसे ब्लाइंड बिल्डर के रूप में लागू किया गया
ब्लाइंड बिल्डर के तीन भाग हैं, जिनमें से प्रत्येक एक अलग स्रोत-कोड फ़ाइल में है:
ToBeBuiltवर्ग (इस उदाहरण में: UserConfig)
- इसका "
Fieldable" इंटरफ़ेस
- बनाने वाला
1. टू-बिल्ट क्लास
टू-इन-बिल्ट क्लास अपने Fieldableइंटरफ़ेस को अपने एकमात्र निर्माता पैरामीटर के रूप में स्वीकार करता है । कंस्ट्रक्टर इसमें से सभी आंतरिक फ़ील्ड सेट करता है, और प्रत्येक को मान्य करता है। सबसे महत्वपूर्ण बात, इस ToBeBuiltवर्ग को अपने बिल्डर का कोई ज्ञान नहीं है।
सार्वजनिक वर्ग UserConfig {
निजी अंतिम स्ट्रिंग sName;
निजी अंतिम int iAge;
निजी अंतिम स्ट्रिंग sFavColor;
सार्वजनिक UserConfig (UserConfig_Fieldable uc_f) {// CONSTRUCTOR
// स्थानांतरण
प्रयत्न {
sName = uc_f.getName ();
} पकड़ (NullPointerException rx) {
नई NullPointerException ("uc_f") फेंकें;
}
iAge = uc_f.getAge ();
sFavColor = uc_f.getFavoriteColor ();
/ / यहां सभी फील्ड्स मान्य करें
}
सार्वजनिक स्ट्रिंग toString () {
वापसी "नाम =" + sName + ", आयु =" + iAge + ", sFavColor =" + sFavColor;
}
}
जैसा कि एक स्मार्ट टिप्पणीकार (जो उनके उत्तर को अनावश्यक रूप से हटा दिया गया है) द्वारा नोट किया गया है, यदि ToBeBuiltवर्ग भी इसका कार्यान्वयन करता है Fieldable, तो इसके एक-और-केवल निर्माता को इसके प्राथमिक और प्रतिलिपि निर्माता दोनों के रूप में उपयोग किया जा सकता है (एक नुकसान यह है कि फ़ील्ड हमेशा मान्य होते हैं, भले ही यह ज्ञात है कि मूल में फ़ील्ड ToBeBuiltमान्य हैं)।
2. " Fieldable" इंटरफ़ेस
ToBeBuiltफ़ील्ड और उसके बिल्डर के बीच फील्डेबल इंटरफ़ेस "ब्रिज" है, जो ऑब्जेक्ट को बनाने के लिए आवश्यक सभी फ़ील्ड्स को परिभाषित करता है। यह इंटरफ़ेस ToBeBuiltवर्गों के निर्माता द्वारा आवश्यक है , और बिल्डर द्वारा कार्यान्वित किया जाता है। चूंकि यह इंटरफ़ेस बिल्डर के अलावा अन्य वर्गों द्वारा कार्यान्वित किया जा सकता है, कोई भी वर्ग ToBeBuiltअपने बिल्डर का उपयोग करने के लिए मजबूर किए बिना, आसानी से क्लास को तुरंत रद्द कर सकता है । इससे ToBeBuiltवर्ग का विस्तार करना भी आसान हो जाता है , जब इसके बिल्डर का विस्तार करना वांछनीय या आवश्यक नहीं है।
जैसा कि एक नीचे अनुभाग में वर्णित है, मैं इस इंटरफ़ेस में फ़ंक्शन को बिल्कुल भी दस्तावेज़ नहीं करता हूं।
सार्वजनिक इंटरफ़ेस UserConfig_Fieldable {
स्ट्रिंग getName ();
int getAge ();
स्ट्रिंग getFavoriteColor ();
}
3. बिल्डर
बिल्डर Fieldableक्लास को लागू करता है । यह बिल्कुल भी मान्य नहीं है, और इस तथ्य पर जोर देने के लिए, इसके सभी क्षेत्र सार्वजनिक और पारस्परिक हैं। हालांकि यह सार्वजनिक पहुंच की आवश्यकता नहीं है, मैं इसे पसंद करता हूं और इसकी सिफारिश करता हूं, क्योंकि यह इस तथ्य को फिर से लागू करता है कि सत्यापन तब तक नहीं होता है जब तक कि ToBeBuiltनिर्माता को नहीं बुलाया जाता है। यह महत्वपूर्ण है, क्योंकि बिल्डर को हेरफेर करने के लिए एक और धागा के लिए संभव है , इससे पहले कि यह ToBeBuiltकंस्ट्रक्टर को पास कर दिया जाए । खेतों की गारंटी देने का एकमात्र तरीका वैध है - यह मानकर कि बिल्डर किसी तरह अपने राज्य को "लॉक" नहीं कर सकता है - ToBeBuiltवर्ग के लिए अंतिम जांच करने के लिए है।
अंत में, Fieldableइंटरफ़ेस के साथ की तरह , मैं इसके किसी भी गेटर्स को दस्तावेज नहीं करता।
सार्वजनिक वर्ग UserConfig_Cfg उपयोक्ता उपयोक्ताConfig_Fieldable {
सार्वजनिक स्ट्रिंग sName;
सार्वजनिक int iAge;
सार्वजनिक स्ट्रिंग sFavColor;
सार्वजनिक UserConfig_Cfg (स्ट्रिंग s_name) {
sName = s_name;
}
// सेल्फ-रिटर्निंग सेटर ... START
सार्वजनिक UserConfig_Cfg आयु (int i_age) {
iAge = i_age;
इसे वापस करो;
}
सार्वजनिक UserConfig_Cfg पसंदीदाकाला (स्ट्रिंग s_color) {
sFavColor = s_color;
इसे वापस करो;
}
// सेल्फ-रिटर्निंग सेटर ... END
//getters...START
सार्वजनिक स्ट्रिंग getName () {
वापसी sName;
}
सार्वजनिक int getAge () {
वापसी iAge;
}
सार्वजनिक स्ट्रिंग getFavoriteColor () {
वापसी sFavColor;
}
//getters...END
सार्वजनिक UserConfig बिल्ड () {
वापसी (नया यूजर कॉनफिग (यह));
}
}
ब्लाइंड बिल्डर के साथ एक क्लास को इंस्टेंट करना
UserConfig uc = new UserConfig_Cfg ("Kermit")। आयु (50) .favoriteColor ("हरा")। build ();
एकमात्र अंतर " UserConfig_Cfg" के बजाय " UserConfig.Cfg" है
टिप्पणियाँ
नुकसान:
- ब्लाइंड बिल्डर्स अपने
ToBeBuiltवर्ग के निजी सदस्यों तक नहीं पहुँच सकते हैं ,
- वे अधिक क्रियात्मक हैं, क्योंकि बिल्डर और इंटरफ़ेस दोनों में गेटर्स की आवश्यकता होती है।
- एक एकल वर्ग के लिए सब कुछ अब केवल एक स्थान पर नहीं है ।
एक ब्लाइंड बिल्डर संकलित करना सीधे-आगे है:
ToBeBuilt_Fieldable
ToBeBuilt
ToBeBuilt_Cfg
Fieldableइंटरफ़ेस पूरी तरह से वैकल्पिक है
ToBeBuiltकुछ आवश्यक क्षेत्रों के साथ एक वर्ग के लिए - जैसे कि यह UserConfigउदाहरण वर्ग, कंस्ट्रक्टर बस हो सकता है
सार्वजनिक UserConfig (स्ट्रिंग s_name, int i_age, स्ट्रिंग s_favColor) {
और बिल्डर के साथ में बुलाया
सार्वजनिक UserConfig बिल्ड () {
वापसी (नया UserConfig (getName) (), getAge (), getFavoriteColor ());
}
या यहां तक कि गेटर्स को खत्म करके (बिल्डर में) पूरी तरह से:
वापसी (नया यूजर कॉनफिग (sName, iAge, sFavoriteColor));
सीधे खेतों से गुजरते हुए, ToBeBuiltक्लास "अंधा" (इसके निर्माता से अनजान) के रूप में यह Fieldableइंटरफ़ेस के साथ है। हालाँकि, उन ToBeBuiltवर्गों के लिए जिनका उद्देश्य "कई बार विस्तारित और उप-विस्तारित" होना है (जो कि इस पद के शीर्षक में है), किसी भी क्षेत्र में किसी भी बदलाव के लिए हर उप-वर्ग में, प्रत्येक बिल्डर और निर्माता में परिवर्तन आवश्यक हैं ToBeBuilt। जैसे-जैसे खेतों और उप-वर्गों की संख्या बढ़ती है, यह बनाए रखने के लिए अव्यावहारिक हो जाता है।
(वास्तव में, कुछ आवश्यक क्षेत्रों के साथ, एक बिल्डर का उपयोग करना अधिक हो सकता है। जो लोग रुचि रखते हैं, उनके लिए यहां मेरी निजी लाइब्रेरी में कुछ बड़े फील्डेबल इंटरफेस का नमूना है।)
उप-पैकेज में माध्यमिक कक्षाएं
मैं सभी बिल्डर और Fieldableवर्गों को चुनता हूं , सभी ब्लाइंड बिल्डर्स के लिए, उनकी ToBeBuiltकक्षा के एक उप-पैकेज में । उप-पैकेज को हमेशा " z" नाम दिया जाता है । यह इन द्वितीयक कक्षाओं को JavaDoc पैकेज सूची को अव्यवस्थित करने से रोकता है। उदाहरण के लिए
library.class.my.UserConfig
library.class.my.z.UserConfig_Fieldable
library.class.my.z.UserConfig_Cfg
वैधता उदाहरण
जैसा कि ऊपर उल्लेख किया गया है, सभी सत्यापन ToBeBuiltनिर्माणकर्ता में होते हैं। यहाँ उदाहरण सत्यापन कोड के साथ फिर से निर्माता है:
सार्वजनिक UserConfig (UserConfig_Fieldable uc_f) {
// स्थानांतरण
प्रयत्न {
sName = uc_f.getName ();
} पकड़ (NullPointerException rx) {
नई NullPointerException ("uc_f") फेंकें;
}
iAge = uc_f.getAge ();
sFavColor = uc_f.getFavoriteColor ();
// सत्यापित करें (वास्तव में पैटर्न को पूर्व-संकलित करना चाहिए ...)
प्रयत्न {
अगर (पैटर्न। pile ("\\ w +")। मिलान करने वाला (नाम) .matches ()! {
नए IllegalArgumentException को फेंकें ("uc_f.getName () (\" "+ sName +" \ ") खाली नहीं हो सकता है, और इसमें केवल अक्षर अंक और अंडरस्कोर शामिल होने चाहिए।");
}
} पकड़ (NullPointerException rx) {
नया NullPointerException ("uc_f.getName ()") फेंकें;
}
अगर (iAge <0) {
नई IllegalArgumentException फेंकें ("uc_f.getAge () (" + iAge + ") शून्य से कम है।");
}
प्रयत्न {
अगर (पैटर्न.कॉमपाइल ("(?: रेड | ब्लू | ग्रीन | हॉट पिंक)")। मैचर (sFavColor) .matches ()) {
नई IllegalArgumentException फेंकें ("uc_f.getFavoriteColor () (\" "+ uc_f.getFavoriteColor () +" "\") लाल, नीला, हरा या गर्म गुलाबी नहीं है।));
}
} पकड़ (NullPointerException rx) {
नए NullPointerException ("uc_f.getFavoriteColor ()") को फेंक दें;
}
}
डॉक्यूमेंटेशन बिल्डर्स
यह खंड बलोच बिल्डर्स और ब्लाइंड बिल्डर्स दोनों के लिए लागू है। यह प्रदर्शित करता है कि मैं इस डिजाइन में कक्षाओं का दस्तावेज कैसे बनाता हूं, (बिल्डर में) और उनके गेटर्स ( ToBeBuiltकक्षा में) सीधे एक-दूसरे को क्रॉस-रेफ़र करते हैं - एक माउस-क्लिक के साथ, और उपयोगकर्ता को यह जानने की आवश्यकता के बिना कि कहां है उन कार्यों वास्तव में रहते हैं - और डेवलपर के बिना कुछ भी अनावश्यक रूप से दस्तावेज़ करने के लिए।
गेटर्स: ToBeBuiltकेवल कक्षाओं में
गेट्स को केवल ToBeBuiltकक्षा में प्रलेखित किया जाता है । दोनों वर्गों _Fieldableऔर_Cfg वर्गों में बराबर प्राप्तकर्ताओं को अनदेखा किया जाता है। मैं उन्हें बिल्कुल भी दस्तावेज नहीं देता।
/ **
<P> उपयोगकर्ता की आयु। </ P>
@ ग्रेट उपयोगकर्ता की उम्र का प्रतिनिधित्व करने वाला एक इंटर्न।
@ हम उपयोगकर्ता कांफिग_फैग # उम्र (इंट)
@ वह getName ()
** /
सार्वजनिक int getAge () {
वापसी iAge;
}
पहला @seeइसके सेटर का लिंक है, जो बिल्डर क्लास में है।
सेटर्स: बिल्डर-क्लास में
सेटर का दस्तावेजीकरण कियाToBeBuilt जाता है जैसे कि वह कक्षा में है , और यह भी मानो कि वह सत्यापन करता है (जो वास्तव में ToBeBuiltनिर्माणकर्ता द्वारा किया जाता है )। तारांकन चिह्न (" *") एक दृश्य सुराग है जो दर्शाता है कि लिंक का लक्ष्य किसी अन्य वर्ग में है।
/ **
<P> उपयोगकर्ता की आयु निर्धारित करें। </ P>
@ अपरम__ शून्य से कम नहीं हो सकता। {@Code UserConfig # getName () getName ()} * के साथ जाओ।
@ वे #favoriteColor (स्ट्रिंग)
** /
सार्वजनिक UserConfig_Cfg आयु (int i_age) {
iAge = i_age;
इसे वापस करो;
}
अग्रिम जानकारी
इसे एक साथ रखना: ब्लाइंड बिल्डर उदाहरण का पूरा स्रोत, पूर्ण प्रलेखन के साथ
UserConfig.java
आयात java.util.regex.Pattern;
/ **
<P> किसी उपयोगकर्ता के बारे में जानकारी - <I> [बिल्डर: UserConfig_Cfg] </ I> / />
<P> सभी वर्गों का सत्यापन इस वर्ग के निर्माणकर्ता में होता है। हालांकि, प्रत्येक सत्यापन की आवश्यकता केवल बिल्डर के सेटर कार्यों में दस्तावेज है। </ P>
<P> {@ कोड जावा xbn.z.xmpl.lang.builder.finalv.UserConfig} </ P>
** /
सार्वजनिक वर्ग UserConfig {
सार्वजनिक स्थिर अंतिम शून्य मुख्य (स्ट्रिंग [] igno_red) {
UserConfig uc = new UserConfig_Cfg ("Kermit")। आयु (50) .favoriteColor ("हरा")। build ();
Println (यूसी);
}
निजी अंतिम स्ट्रिंग sName;
निजी अंतिम int iAge;
निजी अंतिम स्ट्रिंग sFavColor;
/ **
<P> एक नया उदाहरण बनाएं। यह सभी क्षेत्रों को सेट और मान्य करता है। </ P>
@param uc_f {@code null} नहीं हो सकता।
** /
सार्वजनिक UserConfig (UserConfig_Fieldable uc_f) {
// स्थानांतरण
प्रयत्न {
sName = uc_f.getName ();
} पकड़ (NullPointerException rx) {
नई NullPointerException ("uc_f") फेंकें;
}
iAge = uc_f.getAge ();
sFavColor = uc_f.getFavoriteColor ();
// सत्यापित करें
प्रयत्न {
अगर (पैटर्न। pile ("\\ w +")। मिलान करने वाला (नाम) .matches ()! {
नए IllegalArgumentException को फेंकें ("uc_f.getName () (\" "+ sName +" \ ") खाली नहीं हो सकता है, और इसमें केवल अक्षर अंक और अंडरस्कोर शामिल होने चाहिए।");
}
} पकड़ (NullPointerException rx) {
नया NullPointerException ("uc_f.getName ()") फेंकें;
}
अगर (iAge <0) {
नई IllegalArgumentException फेंकें ("uc_f.getAge () (" + iAge + ") शून्य से कम है।");
}
प्रयत्न {
अगर (पैटर्न.कॉमपाइल ("(?: रेड | ब्लू | ग्रीन | हॉट पिंक)")। मैचर (sFavColor) .matches ()) {
नई IllegalArgumentException फेंकें ("uc_f.getFavoriteColor () (\" "+ uc_f.getFavoriteColor () +" "\") लाल, नीला, हरा या गर्म गुलाबी नहीं है।));
}
} पकड़ (NullPointerException rx) {
नए NullPointerException ("uc_f.getFavoriteColor ()") को फेंक दें;
}
}
//getters...START
/ **
<P> उपयोगकर्ता का नाम। </ P>
@ ग्रेट एक गैर - {@ कोड नल}, गैर-रिक्त स्ट्रिंग।
@see UserConfig_Cfg # UserConfig_Cfg (स्ट्रिंग)
@ हम # आगा ()
@ वह #getFavoriteColor ()
** /
सार्वजनिक स्ट्रिंग getName () {
वापसी sName;
}
/ **
<P> उपयोगकर्ता की आयु। </ P>
@ ग्रेट एक संख्या से अधिक-से-या-बराबर-शून्य।
@ हम उपयोगकर्ता कांफिग_फैग # उम्र (इंट)
@ हम # भूलनाम ()
** /
सार्वजनिक int getAge () {
वापसी iAge;
}
/ **
<P> उपयोगकर्ता का पसंदीदा रंग। </ P>
@ ग्रेट एक गैर - {@ कोड नल}, गैर-रिक्त स्ट्रिंग।
@ हम उपयोगकर्ता कांफिग_फैग # उम्र (इंट)
@ हम # भूलनाम ()
** /
सार्वजनिक स्ट्रिंग getFavoriteColor () {
वापसी sFavColor;
}
//getters...END
सार्वजनिक स्ट्रिंग toString () {
वापसी "getName () =" + getName () + ", getAge () =" + getAge () + ", getFavoriteColor () =" + getFavoriteColor ();
}
}
UserConfig_Fieldable.java
/ **
<P> {@link UserConfig} {@code UserConfig # UserConfig (UserConfig_Fieldable) कंस्ट्रक्टर} द्वारा आवश्यक है। </ P>
** /
सार्वजनिक इंटरफ़ेस UserConfig_Fieldable {
स्ट्रिंग getName ();
int getAge ();
स्ट्रिंग getFavoriteColor ();
}
UserConfig_Cfg.java
आयात java.util.regex.Pattern;
/ **
<P> बिल्डर के लिए {@link UserConfig}। </ P>
<P> सभी क्षेत्रों का सत्यापन <CODE> UserConfig </ CODE> कंस्ट्रक्टर में होता है। हालाँकि, प्रत्येक सत्यापन की आवश्यकता केवल इस वर्ग सेटर कार्यों में ही है। </ P>
** /
सार्वजनिक वर्ग UserConfig_Cfg उपयोक्ता उपयोक्ताConfig_Fieldable {
सार्वजनिक स्ट्रिंग sName;
सार्वजनिक int iAge;
सार्वजनिक स्ट्रिंग sFavColor;
/ **
<P> उपयोगकर्ता के नाम के साथ एक नया उदाहरण बनाएं। </ P>
@param__name {@code null} या रिक्त नहीं हो सकता है, और इसमें केवल अक्षर, अंक और अंडरस्कोर शामिल होने चाहिए। {@Code UserConfig # getName () getName ()} {@ कोड ()} के साथ प्राप्त करें ।
** /
सार्वजनिक UserConfig_Cfg (स्ट्रिंग s_name) {
sName = s_name;
}
// सेल्फ-रिटर्निंग सेटर ... START
/ **
<P> उपयोगकर्ता की आयु निर्धारित करें। </ P>
@ अपरम__ शून्य से कम नहीं हो सकता। {@Code UserConfig # getName () getName ()} {@ कोड ()} के साथ प्राप्त करें ।
@ वे #favoriteColor (स्ट्रिंग)
** /
सार्वजनिक UserConfig_Cfg आयु (int i_age) {
iAge = i_age;
इसे वापस करो;
}
/ **
<P> उपयोगकर्ता का पसंदीदा रंग सेट करें। </ P>
@param__color {@code "लाल"}, {@code "नीला"}, {@code हरा}, या {@code "गर्म गुलाबी"} होना चाहिए। {@Code UserConfig # getName () getName ()} {@ कोड ()} * के साथ प्राप्त करें।
@ वे # चरण (इंट)
** /
सार्वजनिक UserConfig_Cfg पसंदीदाकाला (स्ट्रिंग s_color) {
sFavColor = s_color;
इसे वापस करो;
}
// सेल्फ-रिटर्निंग सेटर ... END
//getters...START
सार्वजनिक स्ट्रिंग getName () {
वापसी sName;
}
सार्वजनिक int getAge () {
वापसी iAge;
}
सार्वजनिक स्ट्रिंग getFavoriteColor () {
वापसी sFavColor;
}
//getters...END
/ **
<P> कॉन्फ़िगर के रूप में UserConfig बनाएँ। </ P>
@return <CODE> (नया {@link UserConfig # UserConfig (UserConfig_Fieldable) UserConfig} (यह)) </ CODE>
** /
सार्वजनिक UserConfig बिल्ड () {
वापसी (नया यूजर कॉनफिग (यह));
}
}