2009-04-26 5 views
6

मेरी जावा परियोजना में, मेरे पास विभिन्न प्रकार के व्यापारियों का एक वेक्टर है। इन विभिन्न प्रकार के व्यापारी व्यापारी वर्ग के उप-वर्ग हैं। अभी, मेरे पास एक तरीका है जो ट्रेडर को तर्क के रूप में लेता है और वेक्टर में 50 या उससे अधिक बार स्टोर करता है। मुझे समस्याएं आ रही हैं क्योंकि एक ही ऑब्जेक्ट को 50 बार स्टोर करना एक ही ऑब्जेक्ट के 50 संदर्भ को संग्रहीत कर रहा है। मुझे वस्तु के 50 प्रतियों स्टोर करने की आवश्यकता है। मैंने Clone को कार्यान्वित करने के बारे में शोध किया है, लेकिन मैं नहीं चाहता कि प्रोग्रामर एक प्रकार के व्यापारी को परिभाषित करने के लिए अपनी कक्षा क्लोनबल बनाने की चिंता करें। इसके अलावा, जैसा कि this page द्वारा इंगित किया गया है, क्लोन लागू करने से सभी प्रकार की समस्याएं पैदा होती हैं। मुझे नहीं लगता कि एक कॉपी कन्स्ट्रक्टर या तो काम करेगा क्योंकि अगर मैंने ट्रेडर क्लास में एक को परिभाषित किया है, तो यह उस व्यापारी के प्रकार को नहीं जानता है, जिसकी प्रतिलिपि बनाई जा रही थी और सिर्फ एक सामान्य व्यापारी बनें। मैं क्या कर सकता हूँ?जावा में क्लोन को लागू करने के लिए कोई विकल्प हैं?

संपादित करें: मैं वास्तव में किसी निश्चित वस्तु की सटीक प्रतियां बनाना नहीं चाहता हूं। मैं वास्तव में क्या करने की कोशिश कर रहा हूं वेक्टर को ट्रेडर्स की एक निश्चित संख्या जोड़ना है। समस्या यह है कि उपयोगकर्ता को एक तर्क में निर्दिष्ट करने की आवश्यकता होती है कि वह किस प्रकार का व्यापारी जोड़ना चाहता है। यहाँ मैं क्या करना है कोशिश कर रहा हूँ का एक उदाहरण है: (हालांकि मेरी वाक्य रचना पूरी तरह से काल्पनिक है)

public void addTraders(*traderType*) 
{ 
    tradervect.add(new *traderType*()) 
} 

मैं जावा में कुछ इस तरह कैसे प्राप्त कर सकते हैं?

उत्तर

2

बस एक सार प्रतिलिपि विधि जोड़ें। आप कॉन्वेंट रिटर्न प्रकारों का उपयोग कर सकते हैं ताकि व्युत्पन्न प्रकार एक व्युत्पन्न उदाहरण लौटने के लिए निर्दिष्ट किया गया हो, जो महत्वपूर्ण हो या न हो।

public interface Trader { 
    Trader copyTrader(); 
    ... 
} 


public final class MyTrader implements Trader { 
    MyTrader copyTrader() { 
     return new MyTrader(this); 
    } 
    ... 
} 

कभी कभी तुम क्लोन और फिर एक ठीक से टाइप किया संग्रह वापस जाने के लिए की जरूरत है कि Trader के व्युत्पन्न प्रकार का एक संग्रह का सामान्य रूप से सौदा कर सकते हैं। उस के लिए आप एक मुहावरेदार रास्ते में जेनरिक का उपयोग कर सकते हैं:

public interface Trader<THIS extends Trader> { 
    THIS copyTrader(); 
    ... 
} 


public final class MyTrader implements Trader<MyTrader> { 
    public MyTrader copyTrader() { 
     return new MyTrader(this); 
    } 
    ... 
} 
+0

मुझे नहीं लगता कि मैं जेनेरिक ट्रेडर क्लास को एक इंटरफ़ेस कैसे बना सकता हूं क्योंकि व्यापारी वर्ग में ऐसे विधियां हैं जिन्हें सुलभ करने की आवश्यकता है। एक इंटरफेस बनाना मतलब होगा कि उन सभी निम्न स्तर के तरीकों से उन वर्गों को व्यापारी वर्ग में परिभाषित करने की अनुमति नहीं दी जाएगी। –

+0

चाहे ट्रेडर एक अमूर्त वर्ग या इंटरफ़ेस अप्रासंगिक है। आम तौर पर एक अमूर्त वर्ग पर एक इंटरफेस को प्राथमिकता दी जाती है। विरासत में प्रतिनिधिमंडल भी पसंद करते हैं। –

0

एक विकल्प: आप वस्तुओं serializable कर सकते हैं, तो आप तो क्रमानुसार कर सकते हैं यह deserialize एक प्रति, क्या होता है जब RMI से अधिक एक वस्तु पारित करने के लिए इसी तरह की बनाने के लिए।

त्वरित प्रतिलिपि विधि:

public MyObject copy() { 
    ObjectOutputStream oos = null; 
    ObjectInputStream ois = null; 
    try { 
     ByteArrayOutputStream bos = new ByteArrayOutputStream(); 
     oos = new ObjectOutputStream(bos); 
     oos.writeObject(this); 
     oos.flush(); 
     ByteArrayInputStream bin = 
      new ByteArrayInputStream(bos.toByteArray()); 
     ois = new ObjectInputStream(bin); 
     return (MyObject)ois.readObject(); 
    } catch(Exception e) { 
     return null; 
    } finally { 
     try { 
      oos.close(); 
      ois.close(); 
     } catch (Exception e) { 
      return null; 
     } 
    } 
} 
+0

डाउनवोट क्यों? यह एक जटिल वस्तु को कम करने का एक पर्याप्त तरीका है। हालांकि संसाधन प्रबंधन पूरी तरह से और पूरी तरह टूटा हुआ है। –

+0

क्या यह एकमात्र समाधान है? मैं खुद को यह विश्वास करने के लिए प्रतीत नहीं कर सकता कि इस तरह के एक साधारण ऑपरेशन से इतनी गड़बड़ी होगी। अगर मैं क्लोन को कॉपी करने की अनुमति देने के लिए लागू करता हूं तो क्या होगा। क्या यह भी संभव होगा? –

+0

@Tom: सुनिश्चित नहीं है, लेकिन का उपयोग कर serializing/क्लोनिंग के लिए deserializing सी में प्रति निर्माताओं की बजाय memcpy का उपयोग कर ++ के रूप में के बारे में के रूप में सूक्ष्म है। – Uri

-2

एक तरह से यह जावा के अपने स्ट्रिंग की तरह एक अंतिम वर्ग है, जो स्मृति में एक नई प्रतिलिपि बनाने के लिए वर्ग व्यापारी का एक उद्देश्य के लिए किसी भी परिवर्तन कर देगा बनाने के लिए है , लेकिन यह इसे उपclass करना असंभव हो जाएगा।

ट्रेडर objexts बनाने और कॉपी करने के लिए एक फैक्ट्री विधि का उपयोग करना एक और (बेहतर) तरीका है, जिसका अर्थ है कि आपको डिफ़ॉल्ट कन्स्ट्रक्टर का उपयोग करने की अनुमति नहीं देनी चाहिए, यानी इसे एक निजी बनाएं। इस तरह आप कक्षा के उदाहरणों की संख्या को नियंत्रित कर सकते हैं। http://en.wikipedia.org/wiki/Factory_method

public class Trader { 

    /* prevent constructor so new cant be used outside the factory method */ 
    private Trader() { 
    } 

    /* the factory method */ 
    public static Trader createTrader(int whatKindOfTrader) { 

     switch (whatKindOfTrader) { 
     case 0: 
      return new Trader1(); // extends Trader 
     case 1: 
     default: 
      return new Trader2(); // extends Trader 
     } 
     return new Trader3(); // or throw exception 
    } 
} 

तुम भी, एक और अतिभारित विधि, या एक दूसरा तर्क है कि एक नया एक में एक व्यापारी और यह प्रतियां ले जाता है निर्दिष्ट कर सकता है इस प्रकार क्लोन की जगह मिलते हैं। बीटीडब्ल्यू, आप डिफ़ॉल्ट ऑब्जेक्ट क्लोनिंग को रोकने के लिए क्लोन() विधि को ओवरराइड करना चाहते हैं और CloneNotSupportedException को फेंकना चाहते हैं।

+0

आप केवल एक अंतिम वर्ग की बजाय अपरिवर्तनीय मतलब है। अपरिवर्तनीयता शायद "व्यापारी" वस्तु के लिए थोड़ी दूर जा रही है। –

+0

मैं अपरिवर्तनीय नहीं था, लेकिन अंतिम। एक अंतर है, और व्यक्तिगत रूप से मैं इसका कभी भी उपयोग नहीं करता। लेकिन, फैक्टरी विधि एक सर्वोत्तम अभ्यास है, और यह एक सामान्य डिजाइन पैटर्न बीटीडब्ल्यू है, अपरिवर्तनीय वस्तु सिर्फ इस मामले में उपयोगी नहीं है। – Azder

2

मैं थोड़ा अस्पष्ट हूं कि आप उसी ऑब्जेक्ट के 50 या इतने क्लोन क्यों स्टोर नहीं करना चाहते हैं जब तक कि मूल व्यापारी बाद के व्यापारियों के लिए प्रोटोटाइप (पैटर्न देखें) के रूप में कार्य नहीं करता।

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

मैं सहमत नहीं है कि क्लोन है हमेशा बुराई, यह कभी कभी आवश्यक है। हालांकि, उप-वर्गीकरण की स्थितियों में, बहुत सी चीजें मुश्किल हो जाती हैं।

मैं आपको पढ़ने की सलाह दूंगा (जब आपको मौका मिलता है) ब्लॉच का "प्रभावी जावा", जिसमें उसके कई विषयों को शामिल किया गया है। ब्राचा का विचार यह है कि दूसरों को अपनी कक्षाओं का विस्तार करने देना अच्छा नहीं है, और यदि आप ऐसा करते हैं, तो आपको बहुत अच्छी तरह से दस्तावेज करने की आवश्यकता है कि उन्हें क्या करना होगा और उम्मीद है कि वे आपके निर्देशों का पालन करेंगे। वास्तव में इसे बाईपास करने का कोई तरीका नहीं है। आप अपने व्यापारियों को अपरिवर्तनीय बनाना भी चाह सकते हैं।

सामान्य रूप से क्लोन को लागू करने के लिए आगे बढ़ें, और वर्ग शीर्षलेख में बहुत स्पष्ट रूप से इंगित करें कि आपके व्यापारी से विरासत में कोई भी व्यक्ति और राज्य सदस्यों को जोड़ना एक्स विधियों को लागू करना होगा (निर्दिष्ट करें)।

वास्तविक क्लोनबल बाईपास करने के लिए चाल ढूंढना और अभी भी क्लोन विरासत की समस्या से निपटने वाला नहीं है। यहां कोई रजत बुलेट नहीं है।

+0

आपके उत्तर ने मुझे सोच लिया। अधिक जानकारी के लिए मैंने जो संपादन किया है उसे देखें।:) –

+0

रुको, क्या आप अनिवार्य रूप से कह रहे हैं कि यदि एक्स ट्रेडर को बढ़ाता है, और किसी ने आपके फ़ंक्शन में एक्स का एक उदाहरण पास किया है, तो आप एक और नया एक्स प्राप्त करना चाहते हैं? । – Uri

+0

आप इस व्यवहार चाहते हैं, आप (भयानक) getClass.newInstance मुहावरा का उपयोग करें: traderType.getClass() newInstance() आपको यह सुनिश्चित करना हमेशा एक सार्वजनिक निर्माता है कि वहाँ बनाने के लिए है, और आप शायद कुछ init चाहते विधि जिसे आप इसे वैध स्थिति में लाने के लिए हमेशा कॉल कर सकते हैं। – Uri

0

उरी के अधिकार, राज्य के साथ बहुरूपता कीड़े का एक बड़ा कर सकते हैं को खोलता है।

मुझे लगता है कि उपनिवेश क्लोनेबल और ओवरराइडिंग क्लोन() शायद जाने का सबसे आसान तरीका है। आप विश्वास कर सकते हैं, वापसी प्रकार covariant बनाओ।

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