2012-03-28 7 views
18

यह लगभग एक दार्शनिक प्रश्न है: क्या @ का उपयोग कर सीधे एस 4 ऑब्जेक्ट्स के स्लॉट तक पहुंचना और/या सेट करना बुरा है?क्या एस 4 ऑब्जेक्ट्स स्लॉट का उपयोग सीधे @ @ का उपयोग करना खराब अभ्यास है?

मुझे हमेशा बताया गया है कि यह खराब अभ्यास था, और उपयोगकर्ताओं को "एक्सेसर" एस 4 विधियों का उपयोग करना चाहिए, और डेवलपर्स को अपने उपयोगकर्ताओं को इनके साथ प्रदान करना चाहिए। लेकिन मैं जानना चाहूंगा कि क्या कोई इस के पीछे असली सौदा जानता है?

यहाँ sp पैकेज का उपयोग एक उदाहरण है (लेकिन किसी भी एस 4 वर्ग के लिए सामान्यीकृत किया जा सकता है):

> library(sp) 
> foo <- data.frame(x = runif(5), y = runif(5), bar = runif(5)) 
> coordinates(foo) <- ~x+y 
> class(foo) 
[1] "SpatialPointsDataFrame" 
attr(,"package") 
[1] "sp" 

> str(foo) 
Formal class 'SpatialPointsDataFrame' [package "sp"] with 5 slots 
    [email protected] data  :'data.frame': 5 obs. of 1 variable: 
    .. ..$ bar: num [1:5] 0.621 0.273 0.446 0.174 0.278 
    [email protected] coords.nrs : int [1:2] 1 2 
    [email protected] coords  : num [1:5, 1:2] 0.885 0.763 0.591 0.709 0.925 ... 
    .. ..- attr(*, "dimnames")=List of 2 
    .. .. ..$ : NULL 
    .. .. ..$ : chr [1:2] "x" "y" 
    [email protected] bbox  : num [1:2, 1:2] 0.591 0.155 0.925 0.803 
    .. ..- attr(*, "dimnames")=List of 2 
    .. .. ..$ : chr [1:2] "x" "y" 
    .. .. ..$ : chr [1:2] "min" "max" 
    [email protected] proj4string:Formal class 'CRS' [package "sp"] with 1 slots 
    .. .. [email protected] projargs: chr NA 

> [email protected] 
     bar 
1 0.6213783 
2 0.2725903 
3 0.4458229 
4 0.1743419 
5 0.2779656 
> [email protected] <- data.frame(bar = letters[1:5], baz = runif(5)) 
> [email protected] 
    bar  baz 
1 a 0.22877446 
2 b 0.93206667 
3 c 0.28169866 
4 d 0.08616213 
5 e 0.36713750 
+0

संक्षेप में, आपके प्रश्न का उत्तर "हां, यह बुरा अभ्यास है।" अधिक विस्तृत प्रदर्शनी के लिए मार्टिन के उत्तरों देखें। –

उत्तर

6

सामान्य में बातें अनुमति देते हैं। विचार यह है कि इंटरफेस को कार्यान्वयन से अलग करना है, इस तरह कार्यान्वयन उस कोड के साथ इंटरफेस करने वाले किसी भी कोड को प्रभावित किए बिना काफी बदल सकता है, उदा। आपकी लिपि इसलिए, @ का उपयोग कम मजबूत कोड बनाता है जो कि कुछ वर्षों के समय में काम करने की संभावना कम है। उदाहरण के लिए sp - @ mdsummer द्वारा वर्णित पैकेज में बहुभुज संग्रहीत किए जाने के कार्यान्वयन के कारण गति या प्रगति ज्ञान के कारण परिवर्तन हो सकता है। @ का उपयोग करके, आपका कोड अभी भी काम करता है, इंटरफ़ेस का उपयोग करके आपका कोड टूट जाता है। यदि इंटरफ़ेस भी बदलता है तो छोड़कर। लेकिन कार्यान्वयन में परिवर्तन इंटरफ़ेस परिवर्तनों की तुलना में अधिक संभावना है।

+2

पॉल, मुझे लगता है कि एस 4 स्लॉट किसी ऑब्जेक्ट के सार्वजनिक और निजी हिस्सों के बीच भूरे रंग के क्षेत्र में हैं। एस 4 कक्षाओं के आधिकारिक दस्तावेज के लिए आपको स्लॉट सूचीबद्ध करने और उन्हें समझाए जाने की आवश्यकता होती है, जो काफी सार्वजनिक है। इसलिए मैं स्लॉट्स बदलने के बारे में सतर्क रहूंगा क्योंकि मैं अन्य उपयोगकर्ता-दृश्य परिवर्तनों के बारे में होगा। – cbeleites

+0

आर एस 4 कक्षाएं उचित वस्तु अभिविन्यास भी नहीं हैं जैसा कि मैं समझता हूं, अधिक जानकारी के लिए यह धागा देखें: http://stackoverflow.com/questions/9521651/r-and-object-oriented-programming –

+0

मैं सहमत हूं: "उचित" ऑब्जेक्ट ओरिएंटेशन, मैं अर्ध-आर-सिंटैक्स 'ऑब्जेक्ट @ विधि <- फ़ंक्शन (...) 'में, क्लास से संबंधित होने की विधि की अपेक्षा करता हूं। आर में, अन्य "उचित" ऑब्जेक्ट उन्मुख भाषाओं की तुलना में विधियां अधिक केंद्रीय हैं।
और आईएमएचओ आर का एफओएसएस + इंटरैक्टिव दर्शन शायद ही कभी उपयोगकर्ताओं और डेवलपर्स को अलग करता है। मुझे लगता है कि नो-प्राइवेट-स्लॉट-इन-एस 4 इसका एक लक्षण है। – cbeleites

14

this question में एक stackoverflow-er पूछता क्यों वे एक Bioconductor IRanges वस्तु में end स्लॉट नहीं मिल सकता है ; सब के बाद start(), width(), और end() एक्सेसर्स और start और width स्लॉट हैं। जवाब इसलिए है क्योंकि जिस तरह से कक्षा के साथ इंटरफेस उपयोगकर्ता इसे लागू किया जाता है उससे अलग है। इस मामले में, कार्यान्वयन सरल अवलोकन द्वारा संचालित किया जाता है कि यह तीन मूल्य (प्रारंभ, अंत, चौड़ाई) को स्टोर करने के लिए अंतरिक्ष-कुशल नहीं है जब केवल दो (जो डेवलपर के लिए दो!) पर्याप्त हैं। इंटरफ़ेस और कार्यान्वयन के बीच विचलन के समान लेकिन गहरे उदाहरण अन्य एस 4 ऑब्जेक्ट्स में मौजूद हैं और सामान्य S3 उदाहरणों में lm द्वारा लौटाए गए, जहां कक्षा में संग्रहीत डेटा किसी विशेष मात्रा की मात्रा का प्रतिनिधित्व करने के बजाय अनुरूप गणना के लिए उपयुक्त है उपयोगकर्ता में सबसे अधिक दिलचस्पी हो सकती है। अगर आप उस lm इंस्टेंस में पहुंचने के लिए और एक मान बदलते हैं, उदाहरण के लिए coefficients तत्व में कुछ भी अच्छा नहीं होगा। कार्यान्वयन से इंटरफ़ेस का यह पृथक्करण डेवलपर को उचित और निरंतर उपयोगकर्ता अनुभव प्रदान करने की बहुत स्वतंत्रता देता है, शायद अन्य समान वर्गों के साथ साझा किया जाता है, लेकिन प्रोग्रामिंग भावना को बनाने के तरीकों से कक्षाओं (कार्यान्वयन को बदलने के लिए) को लागू करने के लिए।

यह वास्तव में आपके प्रश्न का उत्तर नहीं है मुझे लगता है कि, लेकिन डेवलपर उपयोगकर्ता उम्मीद नहीं सीधे स्लॉट का उपयोग करने और उपयोगकर्ता उम्मीद नहीं करनी चाहिए प्रत्यक्ष स्लॉट पहुँच वर्ग के साथ बातचीत करने के लिए एक उपयुक्त तरीका हो रहा है।

11

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

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

coordinates() बहुभुज और रेखाओं के लिए विधि प्रत्येक ऑब्जेक्ट के लिए केवल एक केंद्र है, हालांकि बिंदुओं के लिए यह वस्तु से प्रत्येक "समन्वय" देता है, लेकिन ऐसा इसलिए है क्योंकि "अंक" एक-से-एक हैं "। स्पेसियल पॉइंट्स और स्पेटियल पॉइंट्सडेटाफ्रेम के लिए एक ऑब्जेक्ट, एक समन्वय, सत्य भी। यह लाइन और पॉलीगॉन, या लाइन्स और पॉलीगॉन, या स्पेटियललाइन और स्पेटियल पॉलीगॉन, या स्पेटियललाइनसटाफ्रेम और स्पैटियल पॉलीगन्सडेटा फ्रेम के लिए सच नहीं है। ये मूल रूप से दो समन्वय रेखा ट्रैक या> तीन-समन्वय पॉली "छल्ले" के बने होते हैं। प्रत्येक बहु-ब्रांडेड स्पैटलियल पॉलीगॉन से प्रत्येक बहुभुज में प्रत्येक चरम पर समन्वय कैसे प्राप्त करें? आप तब तक नहीं कर सकते जब तक कि आप डेवलपर संरचना में "@" के साथ नहीं पहुंच जाते।

क्या डेवलपर्स का यह छूट प्रदान नहीं किया गया है?नहीं, लाभ किसी भी विशेष उपयोगकर्ता को हिंडसाइट में देख सकते हैं समस्याओं से काफी अधिक है। आम तौर पर, तथ्य यह है कि डेलव में एक बड़ा बोनस है लेकिन आप स्वचालित रूप से डेवलपर की ओर बढ़ते हैं, और यदि आप तरीकों से इसे लपेटे बिना अपने प्रयासों को साझा करना चुनते हैं तो शायद स्थिति को कठिन बनाते हैं।

+0

मैं कहूंगा कि डेवलपर से प्रत्येक उपयोग के मामले के बारे में सोचने के लिए केवल अव्यवहारिक नहीं है: एफओएसएस दर्शन यह है कि यह असंभव है, लेकिन इसके बजाय उपयोगकर्ता के पास * उसके * अवांछित उपयोग के लिए कोड को प्रतिबिंबित करने की संभावना है । – cbeleites

9

एक एस 4 वर्ग के डेवलपर के रूप में, मेरी राय है:

आप @ साथ स्लॉट्स पढ़ा, तो आप ऐसा अपने जोखिम पर (आप आर में क्या काफी सब कुछ की तरह - कुछ प्रसिद्ध के लिए नीचे देखें उदाहरण)। ऐसा कहा जा रहा है कि एस 4 कक्षा के स्लॉट वास्तव में प्रलेखित इंटरफ़ेस का हिस्सा हैं। ।

> microbenchmark (accessor = wl (chondro), direct = [email protected]) 
Unit: nanoseconds 
     expr min  lq median  uq max 
1 accessor 333431 341289.5 346784.5 366737.5 654219 
2 direct 165 212.5 395.0 520.0 1440 

(एक्सेसर समारोह valitidy @wavelength स्लॉट जो अंतर का कारण बनता है लौटने के अलावा जाँच मैं हर सभ्य सार्वजनिक एक्सेसर उम्मीद थी करता है:

@ के माध्यम से पहुंच के मुख्य लाभ मैं देख रहा हूँ गति है वैधता सुनिश्चित करने के लिए कार्य)

मैं समय-महत्वपूर्ण परिस्थितियों में अपनी कक्षा के स्लॉट तक पढ़ने की पहुंच का उपयोग करने की भी सिफारिश करता हूं (उदाहरण के लिए यदि एक ही ऑब्जेक्ट के बहुत सारे सबसेट एक्सेस किए जाते हैं, तो वैधता की जांच करने के लिए यह मूल्यवान हो सकता है एक अपरिवर्तित वस्तु हर बार), और मेरे पी के कोड में एकेज मैं मुख्य रूप से स्लॉट को सीधे पढ़ता हूं, कार्यों की शुरुआत में वैधता सुनिश्चित करता हूं और उन कार्यों के अंत में जहां वस्तु अमान्य हो सकती थी। कोई तर्क दे सकता है कि (आर) डिजाइन निर्णय @<- वैधता की जांच नहीं करता है क्योंकि अभ्यास में भारी ओवरहेड होता है क्योंकि एस 4 ऑब्जेक्ट्स पर काम करने वाली विधियां ऑब्जेक्ट पर भरोसा नहीं कर सकती हैं और इस प्रकार पूरी तरह से पढ़ने के उपयोग के तरीकों को भी वैधता जांच करना है ।

यदि आपको लगता है कि एक स्लॉट तक पहुंच लिखें, तो आपको वास्तव में पता होना चाहिए कि आप क्या कर रहे हैं। @<- कोई वैधता जांच नहीं करता है, आधिकारिक लेखन एक्सेसर को ऐसा करना चाहिए। और, ऑब्जेक्ट के राज्य को सुसंगत रखने के लिए, लिखने वाला एक्सेसर संभवतः एक स्लॉट को अपडेट करने से कहीं अधिक करता है।

तो, यदि आप एक स्लॉट में लिखते हैं, तो खुद को नरक में ढूंढने की उम्मीद करें और शिकायत न करें। ;-)

इस दार्शनिक रेखा के साथ थोड़ा आगे सोचना: मेरा पैकेज जीपीएल के तहत सार्वजनिक है। मैं न केवल आपको अपनी जरूरत के अनुसार कोड अनुकूलित करने की अनुमति देता हूं, लेकिन मैं आपको अपनी आवश्यकताओं के लिए कोड को विकसित/अनुकूलित करने के लिए प्रोत्साहित करना चाहता हूं। दरअसल यह आर में वास्तव में आसान है - स्लॉट तक पहुंच सहित, सामान्य इंटरैक्टिव आर सत्र में सबकुछ पहले से मौजूद है। जो काफी डिजाइन फैसले कि आर बहुत शक्तिशाली बनाने के साथ एक कतार में है, लेकिन यह इंटरफ़ेस से एक वस्तु की सामग्री को अलग करने के अच्छा प्रोग्रामिंग अभ्यास है, this wikipedia article देखने की तरह

> T <- FALSE 
> `+` <- `-` 
> pi <- 3 
> pi + 2 
[1] 1 
+0

संभवतः आपका एस 4 दस्तावेज उपयोगकर्ता को बताता है कि आपको सत्यापन करने की आवश्यकता क्यों है, और एक उचित 'गति' तुलना में बिल्कुल वही सत्यापन शामिल है? यदि सत्यापन छोड़ना एक आम उपयोग केस है, तो क्या आपका एक्सेसर उस अतिरिक्त अनुमति के साथ, उदाहरण के लिए, अनुमति नहीं दे सकता है? –

+0

मार्टिन, '? validObject' आपको बताता है कि ऑब्जेक्ट को 'new()' द्वारा बनाया गया है, और एक उदाहरण देता है कि यह '@<-' के बाद का मामला नहीं है। तो यह दस्तावेज व्यवहार है। – cbeleites

+0

@ मार्टिन: मैं स्किपिंग सत्यापन को सामान्य उपयोग केस नहीं कहूंगा। हालांकि, * * उपयोग का मामला यह है कि डेटा सेट बड़ा है, यानी उपलब्ध रैम को असुविधाजनक रूप से बंद करें। इस प्रकार, आप स्लॉट (मैट्रिक्स या डेटा.फ्रेम) की सामग्री के साथ एक मध्यवर्ती ऑब्जेक्ट का उत्पादन करने का साफ तरीका नहीं लेना चाहते हैं और उसे सबसेट करें। चूंकि अधिक रैम खरीदने के लिए फॉर्म भरने से अधिक डेटा प्राप्त करना आसान है, यह शायद ही कभी नहीं है। तो: ऐसा होता है, लेकिन जो लोग अपनी बाम को अंतिम बाइट तक भरना चाहते हैं उन्हें पता होना चाहिए कि वे क्या कर रहे हैं। – cbeleites

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