2011-06-25 8 views
8

मेरे पास BigDecimal कक्षा का उपयोग कर कोड का एक उचित कोड है और मुझे इंटरफ़ेस की गड़बड़ी से नफरत है।बिगडेसिमल का विस्तार?

मैं निम्न विधियों के साथ स्थिर तरीकों के साथ एक सहायक वर्ग बनाने के द्वारा पूर्णांकों के साथ BigDecimal रों का उपयोग कर के दर्द को कम किया गया है:

compare(BigDecimal first, int second) 
divide(BigDecimal dividend, BigDecimal divisor, int scale) 
divide(BigDecimal dividend, int divisor, int scale) 
divide(int divident, int divisor, int scale) 
multiply(BigDecimal first, BigDecimal second, int scale) 
multiply(BigDecimal first, int second, int scale) 
multiply(int first, int second, int scale) 
zeroPad(BigDecimal value, int totalLength, int scale) 

सब मैं अब के लिए की जरूरत है और कोड थोड़ा और अधिक पठनीय है कि पहले से। हालांकि, मैंने पढ़ा है कि स्थैतिक विधियां एक "बुरी" चीज हैं और वे ओओ-सिद्धांतों का पालन नहीं करते हैं।

यदि मैं BigDecimal का विस्तार करता हूं, तो भी मैं एक नया प्रकार परिभाषित करता हूं और इस प्रकार मुझे अपने ऑब्जेक्ट से उन्हें लपेटने के लिए सभी विधियों को फिर से परिभाषित करना होगा या मैं उन्नत विधियों के साथ परिणामों का उपयोग नहीं कर पाऊंगा । ऐसा करने के लिए एक स्मार्ट चीज नहीं लगती है।

आप इस समस्या से कैसे संपर्क करेंगे?

+0

दिलचस्प, मैंने अपने कोड में लगभग वही स्थिर तरीके बनाये हैं। मेरे लिए, यह पागल है कि 'बिगडिसीमल' में 'डिवाइड (बिगडिसीमल लाभांश, int divisor)' विधि अंतर्निहित नहीं है। पिछली बार जब आपको दशमलव से कुछ विभाजित करने की आवश्यकता थी? मेरे पास किसी भी कोड की गणना में divisor के रूप में 'int' के अलावा कुछ भी नहीं था। (यह नहीं कह रहा कि मामले मौजूद नहीं हैं, लेकिन divisor के रूप में 'int' सबसे संभावित परिदृश्य की तरह लगता है कि यह मानक पुस्तकालय सहित लायक होगा)। – ryvantage

उत्तर

5

मैं वैसे ही करूँगा जैसा आपके पास है!

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

लेकिन जावा के सिंटैक्स को देखते हुए, गणित-आधारित अभिव्यक्तियों के लिए एपीआई बनाना वाकई मुश्किल है। मैं वर्तमान BigInteger एपीआई के साथ दो समस्याएं हैं:

  • यह बहुत सामान्य गणित-अंकन के पास नहीं है
  • ऐसा सममित ऑपरेटरों के लिए असममित है जोड़ सकते हैं और गुणा

[ऑपरेटर-अधिभार सी ++ की कुछ विशेषताओं में से एक है, मुझे जावा में याद आती है]

जो अधिक पढ़ा जा सकता है?

BigInteger a = ...; 
BigInteger b = ...; 
BigInteger c = divide(a, b); 

या

BigInteger a = ...; 
BigInteger b = ...; 
BigInteger c = a.divide(b); 

व्यक्तिगत रूप से, मैं दूसरे संस्करण पसंद करते हैं।

खराब ऐसे मामले हैं जहां विभिन्न आधार प्रकारों की संख्या एक ही अभिव्यक्ति का हिस्सा हैं। जैसे

int a = ...; 
BigInteger b = ...; 
BigInteger c = divide(a, b); 

या

int a = ...; 
BigInteger b = ...; 
BigInteger c = BigInteger.valuOf(a).divide(b); 

भी बड़ा इसी गणित अंकन में छोटे परिवर्तन से अंकन में मतभेद पर विचार करें:

  • (a-b)*ca.subtract(b).multiply(c) या multiply(subtract(a,b),c)
  • c*(a-b) लिए अनुवाद किया हैमें अनुवाद किया गया हैया multiply(c,subtract(a,b))

मेरे लिए, "शुद्ध" ओ-ओ आधारित नोटेशन की तुलना में स्थिर विधि नोटेशन लिखना और पढ़ना आसान है।

+0

मुझे लगता है कि सब कुछ सबसे आसान सुरक्षित तरीका है, क्योंकि अगर मैं बिगडेसिमल लपेटता हूं, तो यह अब जेडीबीसी के साथ काम नहीं करेगा। – stivlo

4

BigDecimal का विस्तार न करें, इसके चारों ओर एक रैपर वर्ग (जैसे आपके पास) या कॉमन्स मैथ जैसे अन्य ढांचे का उपयोग करें। आप एक वर्ग है कि एक और वर्ग (यानी आपके मामले में BigDecimal) फैली हुई है बनाते हैं org.apache.commons.math.dfp.Dfp

+0

मैं डीएफपी को देख लूंगा। तो एक रैपर वर्ग में मुझे लगता है कि ऑब्जेक्ट के अंदर एक बिगडिसीमल होगा, और चूंकि बिगडेसिमल से असंबंधित है, मुझे बिगडिसीमल और मेरे सभी तरीकों से संबंधित सभी विधियों को फिर से लिखना होगा। यह दृष्टिकोण कैसे बेहतर हो सकता है? ऐसा लगता है कि बिगडेसिमल को विस्तारित करने का लगभग एक ही प्रयास है। बस समझने की कोशिश कर रहा हूं, मुझे गलत साबित होने में खुशी होगी। – stivlo

+1

और सोचकर यह बेहतर होगा, क्योंकि मुझे केवल सभी तरीकों को प्रदान करने की आवश्यकता नहीं है, इसलिए मैं केवल MyBigDecimal और BigDecimal उदाहरणों को मिश्रित नहीं करता। – stivlo

+0

org.apache.commons.math.dfp.Dfp से लिंक मान्य नहीं है –

0

, बच्चे वर्ग अभी भी सभी है -

Dfp आप क्या चाहते हैं के समान दिखता है माता-पिता (सुपर) वर्ग के गुण। आपके मामले में, यदि आप लिखना:

public class UsableBigDecimal extends BigDecimal { 
... 
} 

किसी भी UsableBigDecimal वस्तुओं अभी भी BigDecimal के उदाहरण हो सकता है, के बाद से यह उनकी सुपर क्लास है। आप उन्हें किसी भी BigDecimal ऑब्जेक्ट के रूप में उपयोग करने में सक्षम होंगे, आपकी स्थिर उपयोगिता विधियों को शामिल किया गया है।

उसने कहा, मेरी राय में स्थिर उपयोगिता विधियां कोर जावा कक्षाओं से निपटने के दौरान सामान्य कोड साझा करने के तरीके के रूप में काफी स्वीकार्य हैं।

+0

MyBigDecimal BigDecimal का एक उदाहरण होगा और इसका उपयोग इस तरह किया जा सकता है, लेकिन इसके विपरीत नहीं, इसलिए यदि मैं बेस क्लास की विधि को कॉल करता हूं व्युत्पन्न वर्ग यह एक नया बेस क्लास उदाहरण देता है और मैं व्युत्पन्न क्लास विधियों का उपयोग इस पर और अधिक नहीं कर सकता (एक प्रतिलिपि निर्माता के अलावा, लेकिन यह कोड को और भी बेकार बना देगा)। – stivlo

2

क्या आप कृपया मुझे स्पष्टीकरण दे सकते हैं कि "मैं एक नया प्रकार परिभाषित करता हूं और इस प्रकार मुझे अपने ऑब्जेक्ट से उन्हें लपेटने के लिए सभी विधियों को दोबारा परिभाषित करना होगा या मैं सक्षम नहीं होगा संवर्धित विधियों के साथ परिणामों का उपयोग करने के लिए। "

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

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

तो आदेश में एक BigDecimal विधि रैप करने के लिए अपने कस्टम प्रकार वापस जाने के लिए में:

inhertance साथ

, तो आपको निम्न की तरह कुछ करना चाहते हैं:

@Override public MyBD divide(int second) 
{ 
    return new MyBD(this.divide(second)); 
} 
प्रतिनिधिमंडल के साथ

(यानी रचना) , है न चाहते हैं:

public MyBD divide(int second) 
{ 
    return new MyBD(_innerBigDecimal.divide(second)); 
} 

स्थिर सहायक तरीकों के साथ, आप कर चाहते हैं:

public static BigDecimal divide(BigDecimal first, int second) 
{ 
    return first.divide(second); 
} 
+0

उदाहरण के लिए अगर मैं परिभाषित MyBigDecimal BigDecimal फैली अगर मैं एक विधि आधार वर्ग में परिभाषित का उपयोग यह एक BigDecimal है और इस तरह इस तरह कोड काम नहीं करेगा वापस आ जाएगी:। नई MyBigDecimal ("12.89") विभाजन (AnotherBigDecimal) .methodOfMyBigDecimal() – stivlo

+0

ठीक है, समझ गया। तो हाँ, आपको अपने खुद के संस्करण के साथ आवश्यक मूल बिगडिमल विधियों को लपेटना चाहिए। बस ध्यान दें कि यह _wrapping job_ आपको जो भी विकल्प लेना है, चाहे वह विरासत, प्रतिनिधिमंडल हो, लेकिन आपके स्थिर सहायक कार्यों के साथ भी आप ऐसा कर रहे हैं! – superjos

+0

मैंने आपकी टिप्पणी के बाद उत्तर अपडेट किया – superjos

-4

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

+0

मान लें कि मैं सभी दशमलव प्रदर्शित करने के लिए एक निश्चित प्रारूप का उपयोग करना चाहता हूं, आदर्श रूप में मैं टूस्ट्रिंग को ओवरराइड कर दूंगा। ऐसा करने का प्राकृतिक तरीका बिगडेसिमल का विस्तार कर रहा है, लेकिन इसके रचनाकारों को ओवरराइड करने की भी आवश्यकता है इसलिए मैं इसे लपेटना पसंद करता हूं। –

+0

@LluisMartinez ऐसा करने का प्राकृतिक तरीका वास्तव में एक नया प्रारूप वर्ग लिखना है। 'toString()' केवल एक डिबगिंग खिलौना है। – EJP