2009-07-06 20 views
10

क्या किसी ने जावा में कॉपी कन्स्ट्रक्टर/फैक्ट्री विधियों आदि के लिए सर्वोत्तम सुझावों और नामकरण सम्मेलनों का सुझाव दिया है या स्थापित किया है? विशेष रूप से, कहें कि मेरे पास कक्षा Thing है और मुझे कहीं भी एक विधि चाहिए जो Thing को Thing के समान मान के साथ (या उदाहरण के रूप में यदि यह एक उदाहरण विधि है) के समान मूल्य देता है। क्या आपके पास यह कन्स्ट्रक्टर या स्थैतिक फैक्ट्री विधि या उदाहरण विधि के रूप में होगा? आप इसे क्या कहेंगे?यदि आप जावा में क्लोन नहीं करते हैं तो आप क्या करते हैं और आप इसे क्या कहते हैं?

शीर्षक के अनुसार, मैं clone() और Cloneable से बचना चाहता हूं।

+0

आप क्लोन() और क्लोनेबल से क्यों बचना चाहते हैं? –

+0

@ थॉमस ओवेन्स, यहां देखें: http://www.artima.com/intv/bloch13.html – Yishai

+0

जवाब के रूप में राज्य प्रतिलिपि निर्माता: कॉपी कन्स्ट्रक्टर सभी मामलों को ठीक से संभाल नहीं करता है। उदाहरण के लिए जब आप कंक्रीट क्लास को नहीं जानते हैं (लेकिन आप अभी भी अपने क्लोन/प्रतिलिपि/whateveryoucallit विधि के अंदर कॉपी कन्स्ट्रक्टर का उपयोग कर सकते हैं)। –

उत्तर

0

यदि आप चाहें तो clone() -method को ओवरराइट कर सकते हैं। एक अन्य प्रयुक्त अभ्यास एक निर्माता है, जो इस प्रकार का एक वस्तु लेता है, यानी new ArrayList(anotherList)

3

मैं इसे एक प्रति विधि या प्रतिलिपि निर्माता (जैसा भी मामला हो) कहूंगा। अगर यह एक स्थिर विधि थी, तो मैं इसे एक कारखाना कहूंगा।

क्या करना है इसके संदर्भ में, सबसे लचीला और लंबा जीवन विकल्प एक प्रतिलिपि निर्माता है। यह सबक्लास को माता-पिता की तरह खुद को कॉपी करने की क्षमता देता है।

2

मैं तो एक निर्माता

... 
public Thing(Thing copyFrom) 
{ 
    attr1 = copyFrom.attr1; 
    attr2 = copyFrom.attr2; 
    //etc... 
} 

करना चाहते हैं जब आप इसे

Thing copy = new Thing(copy from me); 
0

क्लोन करने के लिए आपके पास कुछ विकल्प मिल गया है, Cloneable लागू, एक प्रति निर्माता, लेकिन मेरी पसंदीदा तरीका जोड़ना चाहते हैं एक विधि (स्थैतिक या उदाहरण) का उपयोग करना है जिसमें एक नाम है जो कॉपी ऑपरेशन कर रहा है, यह वर्णनात्मक है - क्या यह एक गहरी या उथली प्रतिलिपि है, आदि

15

प्रभावी जावा रीकॉम mends निम्नलिखित में से किसी:

  1. एक प्रति निर्माता (के रूप में दूसरों के द्वारा ध्यान दिया):

    सार्वजनिक मद (आइटम आइटम)

  2. एक प्रति कारखाने विधि:

    सार्वजनिक स्थैतिक आइटम नया इंस्टेंस (आइटम आइटम)

(इसके अलावा, अपरिवर्तनीय के लिए कोई प्रतिलिपि नहीं)

प्राथमिक अंतर यह है कि # 1 के साथ आप परिणाम की वास्तविक कक्षा चुनते हैं, और # 2 के साथ कार्यान्वयन एक सबक्लास लौटा सकता है। कक्षा के अर्थशास्त्र आपको मार्गदर्शन कर सकते हैं कि कौन सा सबसे अच्छा है।

0

immutable data structures का उपयोग करें। एकमात्र कारण आपको लगता है कि आपको clone() की आवश्यकता है कि आप अपनी वस्तुओं को जगह में बदल रहे हैं। यह करना बंद करो। इस बारे में सोचें कि आप कैसे कर सकते हैं:

  • अपनी कक्षाएं अंतिम बनाएं।
  • अपने कक्षाओं में अंतिम और निजी क्षेत्र बनाएं।

    public Vector3D setX(double x) { 
        return new Vector3D(x, this.y, this.z); 
    } 
    

    तो मुझे लगता है कि मैं क्या कह रहा हूँ है ... मैं उत्परिवर्तन के बजाय प्रति कंस्ट्रक्टर्स उपयोग करते हैं, और मैं:

उदाहरण के लिए, यहाँ एक अपरिवर्तनीय 3D सदिश वस्तु के लिए "सेटर" है उन्हें उस विशेषता के अनुसार नाम दें जिसे मैं संशोधित करना चाहता हूं।

interface Has3DCoords { 
    void setLocation(double x, double y, double z); 

    void copyCoordsTo(Has3DCoords dest); 
} 

फिर आप की तरह कोड का एक टुकड़ा के साथ नकल को क्रियान्वित करेगी::

0

एक अन्य विकल्प स्रोत वस्तु में नकल विधि, जैसे लागू करने के लिए है

class Thing implements Has3DCoords { 
    private Point3D loc; 
    // ... 

    void setLocation(double x, double y, double z) { 
     loc.setLocation(x, y, z); 
     // or: loc = new Point3D(x, y, z); 
    } 

    void copyCoordsTo(Has3DCoords dest) { 
     loc.copyCoordsTo(dest); 
     // or: dest.setLocation(loc.getX(), loc.getY(), loc.getZ()); 
    } 

    OtherThing createOtherThing() { 
     OtherThing result = new OtherThing(); 
     this.copyCoordsTo(result); 
     return result; 
    } 
} 

यह हो सकता है उपयोगी अगर:

  • पूरे ऑब्जेक्ट को क्लोन करना समझ में नहीं आता है
  • वहाँ संबंधित गुण के एक समूह है कि अक्सर एक इकाई के रूप कॉपी कर रहे हैं है
  • आप Thing
  • प्रॉपर्टी की संख्या बड़ी है की एक संपत्ति के रूप में loc बेनकाब करने के लिए नहीं करना चाहते हैं (या कई तरह के समूहों देखते हैं) तो एक कन्स्ट्रक्टर जो उन सभी को पैरामीटर के रूप में आवश्यक था, वह अनावश्यक होगा।
0

यह वस्तुओं को कॉपी करने के लिए सबसे अच्छा तरीका नहीं है, लेकिन निम्नलिखित कभी कभी उपयोगी है अगर आप एक Serializable वस्तु का एक गहरी प्रतिलिपि प्रदर्शन करना चाहते। यह कॉपी कंसल्टर्स लिखने, क्लोनबल लागू करने या फैक्ट्री कक्षाओं को लिखने से बचाता है।

ByteArrayOutputStream bos = new ByteArrayOutputStream(); 
ObjectOutputStream oos = new ObjectOutputStream(bos); 

//Serializes the input object 
oos.writeObject(input); 

ByteArrayInputStream bais = new ByteArrayInputStream(bos.toByteArray()); 
ObjectInputStream ois = new ObjectInputStream(bais); 

//Copy of the input object 
Object output = ois.readObject(); 

अपवादों को संभालने और अच्छी तरह से स्ट्रीम को बंद करने के लिए मत भूलना।

संबंधित मुद्दे

 संबंधित मुद्दे