2009-11-16 25 views
9

मैं ऑब्जेक्ट उन्मुख प्रोग्रामिंग के आसपास अपने सिर को लपेटने की कोशिश कर रहा हूं।ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग - क्लास डिज़ाइन भ्रम

मेरी समझ यह है कि हमारे पास ऑब्जेक्ट्स हैं ताकि हम अपने कार्यक्रमों को वास्तविक जीवन वस्तुओं को दर्पण करने के लिए डिज़ाइन कर सकें।

के एक वर्ग पदानुक्रम लेते हैं:

class Fruit { 
    void Eat() { 

    } 
} 

class Apple extends Fruit { 

} 

जाहिर है, आप फल polymorphically उपयोग कर सकते हैं Eat() आभासी है। लेकिन क्या यह समझ में आता है? फल खुद नहीं खा सकता!

क्या एक फल वस्तु को मानव वस्तु को पारित किया जाना चाहिए जिसमें Eat() फ़ंक्शन है?

मैं इस बारे में सोचने का सही तरीका जानने की कोशिश कर रहा हूं। सामान्य रूप से, प्रोग्रामिंग ऑब्जेक्ट्स वास्तविक जीवन वस्तुओं को दर्पण करना चाहिए?

उत्तर

11

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

सामान्य रूप से आप चाहते हैं कि आपकी कक्षाएं तार्किक डोमेन स्तर इकाइयों का प्रतिनिधित्व करें। कभी-कभी वे वास्तविक दुनिया में भौतिक इकाई से मेल खाते हैं, लेकिन कई मामलों में वे नहीं करते हैं।

मेरी राय में ओओ समस्या अपघटन कुछ प्रोग्रामर आमतौर पर बहुत खराब होते हैं।मुझे नहीं पता कि मैंने स्टीयरिंग व्हील से ली गई कार के बराबर कितनी बार देखा है और मेरे सिर को हिलाकर रख दिया है, जबकि मूल डेवलपर अपने सिर को लपेट नहीं सकता था कि उनके डिजाइन ने बहुत समझ क्यों नहीं ली।

+0

+1 अच्छे उदाहरण। एक और उदाहरण यह होगा कि फल खाद्य इंटरफ़ेस/वर्ग का है और उपभोक्ता वस्तु, जैसे कि व्यक्ति वर्ग की वस्तु, में ईट (खाद्य ई) विधि है। जो MyPerson.Eat (myEdible) को ले जाएगा, ओपी की तरह अनुमान लगा रहा था। – Spoike

+0

सुरक्षित आभासी शून्य OnEaten() {Barf(); } –

0

एक फल वस्तु अपेक्षा एक मानव वस्तु एक खाओ() समारोह है जो करने के लिए पारित कर दिया जाना चाहिए?

हां।

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

0

आप सही हैं कि शायद खाएं() मानव या स्तनपायी या फल की विधि होगी। एक फल में शायद कोई व्यवहार नहीं होता है, और इसलिए कोई तरीका नहीं है।

मैं वास्तविक वस्तुओं से ऑब्जेक्ट में मैपिंग के लिए वास्तविकता में ओओ के लाभों पर अक्सर विचार नहीं करता हूं। ऐसा शायद इसलिए है क्योंकि हम इनवॉइस और ऑर्डर जैसे कम मूर्त अवधारणाओं से निपटते हैं।

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

0

अधिकांश मानव भाषाओं Subject Verb Object

का एक वाक्य संरचना (सरल बयान के लिए) का पालन ग की तरह OOP भाषाओं ++ में, नहीं पूरी तरह विडंबना यह है कि, वस्तु वस्तु है, और इसलिए सामान्य क्रम उलट है यह, पहले आता है:

तो यह C++ 'बेसिक' पैटर्न है: -

object.verb(subject); 

यह वास्तव में बकवास है। अधिकांश वर्गों को subject.verb (ऑब्जेक्ट) इंटरफ़ेस के साथ डिज़ाइन किया गया है। एसवीओ का ज्ञान हालांकि किसी को यह जांचने की इजाजत देता है कि कक्षा इंटरफ़ेस को सही तरीके से डिजाइन करने के लिए डिज़ाइन किया गया है या नहीं (इस मामले में, यह नहीं है)।

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

+2

ऐसा लगता है कि आप इस मामले में और सामान्य रूप से पीछे की तरफ हैं। human.eat (सेब) वह है जिसे हम यहां देख रहे होंगे। प्रसंग क्रिया उपसर्ग)। – Grumdrig

+0

वास्तविक ओएसवी और ओवीएस भाषाएं खूनी दुर्लभ लगती हैं। ओओपी डिजाइन में उचित आदेश के रूप में एसवीओ को औपचारिक बनाने के लिए और भी समर्थन। –

1

मान लीजिए कि आप एक भूखे लोगों के सिम्युलेटर लिख रहे थे, तो मुझे लगता है कि यह कहने के लिए और अधिक समझदारी होगी, जैसा कि आप कहते हैं, Human::Eat(Fruit f) फ़ंक्शन है। आपके फल में विधियां नहीं हो सकतीं क्योंकि फल अपने आप पर बहुत कुछ नहीं करता है, लेकिन इसमें calories संपत्ति हो सकती है, और इसी तरह।

0

मुझे लगता है कि करने के लिए के बारे में करते हैं:

एक

एक

है तो, एक सेब एक फल है, इसलिए विरासत समझ में आता है।

लेकिन, फल ​​(खाने) खाने योग्य हो सकता है, लेकिन इससे पता चलता है कि यह फल की संपत्ति है, न कि एक क्रिया (विधि)।

उदाहरण के लिए, आपके पास अपरिचित सेब हो सकता है, जो खाद्य (खाने योग्य नहीं) होगा ताकि आप इस संपत्ति को सेट कर सकें।

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

अब Has a संरचना के लिए होगा। तो, एक सेब के बीज का मतलब यह होगा कि बीज सेब का विस्तार नहीं करता है, लेकिन एक सेब में बीज का संग्रह होता है।

तो, आपके पास एक डिज़ाइन समस्या है, और मुझे आशा है कि ये दो अवधारणाएं स्पष्ट करने में सहायता कर सकती हैं।

+0

"इज़-ए" (विरासत) और "है-ए" (रचना) समानता चीजों के बारे में सोचने की अच्छी शुरुआत है, लेकिन यह ध्यान देने योग्य है कि इसमें कुछ सीमाएं हैं। "इज़-ए और है-ए" के बारे में सबकुछ सोचने के बजाय "विरासत पर रचना पसंद करना" के लिए जाना बेहतर है क्योंकि उत्तरार्द्ध विरासत के लिए प्राथमिकता की ओर जाता है। बड़ी विरासत संरचनाओं को बनाए रखना मुश्किल है। – Spoike

+0

@Spoike - जब कोई व्यक्ति ओओपी के लिए नया होता है तो इसे सरल रखना सबसे अच्छा शर्त है, और इन दो अवधारणाओं को मुझे लगता है कि इसे आसान रखने में मदद मिलती है। एक बार ये बेहतर समझने के बाद आप समझने के लिए अन्य दृष्टिकोण देख सकते हैं, आईएमओ। –

8

बस असली दुनिया वस्तुओं को मिरर करना शायद ही कभी एक अच्छा विचार है। एक क्लासिक उदाहरण से उधार लेने के लिए - एक कॉफ़ीमेकर को नियंत्रित करने वाला सॉफ़्टवेयर कॉफी सेम और गर्म पानी के बारे में नहीं है - यह कॉफी बनाने के बारे में है।

आपको अपनी असली दुनिया की समस्या के लिए अंतर्निहित अमूर्तता की आवश्यकता है, न केवल ऑब्जेक्ट पदानुक्रमों में संज्ञाओं की प्रतिलिपि बनाएँ।

यदि आपका सेब फल से निकला है, तो क्या यह कोई दिलचस्प व्यवहार जोड़ता है? पदानुक्रम वास्तव में जरूरत है? विरासत आपके सॉफ़्टवेयर में जटिलता का स्तर जोड़ती है और कुछ भी जटिलता बढ़ रही है।आपका सॉफ़्टवेयर बस पालन करने और समझने के लिए थोड़ा कठिन है, आपके परीक्षण में कवर करने के लिए थोड़ा और कुछ है और बग की संभावना सिर्फ थोड़ी बड़ी है।

मुझे लगता है कि ओओपी व्हाइटस्पेस के बारे में अधिक है - जो आप छोड़ रहे हैं वह अधिक महत्वपूर्ण है।

0

सामान्य रूप से, प्रोग्रामिंग ऑब्जेक्ट्स वास्तविक जीवन वस्तुओं को दर्पण करना चाहिए।

ज्यादा नहीं, केवल पर्याप्त है।

ओओपी की मुख्य विशेषताओं में से एक, अमूर्त है। किसी ऑब्जेक्ट के सभी विशेषताओं/विधियों का उपयोग करने में सक्षम होने की आवश्यकता नहीं है।

आपको इसका उपयोग करने के लिए मूलभूत आवश्यकता है।

ऑब्जेक्ट्स के बारे में पूरी बात, डेटा और फ़ंक्शन जो एक ही स्थान पर उस डेटा के बारे में कुछ करने के लिए है।

तो आपके फल वर्ग में मैं Color के रूप में बेहतर होगा या अगर इसे खाया जाएगा तो संकेत होगा। उदाहरण के लिए:

Fruit 
    + color : Color 
    - isMature : Boolean 

    + canBeEaten() : Boolean 
      return isMature 

इस तरह आप अलग अलग फल

apple = Fruit() 
appe.color = Color.red 
out.print("Can this fruit be eaten? %s ", apple.canBeEaten()) 

orange = Fruit() 
orage.color = Color.orange 
out.print("Can this fruit be eaten? %s ", orange.canBeEaten()) 

आदि

आप विशेषताओं (रंग और isMature) दिखाई देता है ऑब्जेक्ट के अंदर जमा हो जाती है बना सकते हैं। इस तरह आपको बाहर से अपने राज्य का ट्रैक रखने की जरूरत नहीं है।

विरासत के लिए, यह केवल तब समझ में आता है जब आपको किसी विधि में नया व्यवहार जोड़ने की आवश्यकता होती है, और हां, विधियां ऑब्जेक्ट्स के गुणों या विशेषताओं से संबंधित होती हैं। जैसा कि आप इंगित करते हैं fruit.eat() अधिक समझ में नहीं आता है।

लेकिन रस से रस प्राप्त करने के लिए एक विधि पर विचार करें।

Fruit 
    + getJuice(): Juice 

Apple -> Fruit 
    + getJuice(): Juice 
     // do what ever is needed internally to create the juice 

Orange -> Fruit 
    + getJuice(): Juice 
     // here, certainly the way to get the juice will be different 
0

मुझे हमेशा 'जानवरों' या 'फल' काउंटर-सहज ज्ञान युक्त उदाहरण मिलते हैं। लोग मॉडल के लिए मुश्किल वस्तुएं हैं, और यह असंभव है कि आपको समान आवश्यकताओं वाले अनुप्रयोगों का सामना करना पड़ेगा।

एंथ्रोपोमोर्फिज़ेशन की अवधारणा का उपयोग वास्तव में प्रतिवादों को असाइन करने में मदद कर सकता है। असल में, कल्पना करें कि आपकी वस्तु एक व्यक्ति है (मैं आम तौर पर डिजाइन सत्रों के दौरान उन्हें चेहरे और अंगों के साथ स्केच करता हूं)।

  • "क्या ज़िम्मेदारियां करता है मेरी वस्तु प्रणाली भीतर है":

    अब आप अपने वस्तु के बारे में इन सवाल पूछ सकते हैं

  • "इस वस्तु xxx कर के लिए जिम्मेदार है, या xxxएक और वस्तु की जिम्मेदारी होनी चाहिए?"
  • "क्या यह ऑब्जेक्ट इससे अधिक कर रहा है?" (उदाहरण के लिएयदि यह कुछ गणना करने के लिए डिज़ाइन किया गया है, तो यह मान लोड करने के लिए ज़िम्मेदार नहीं होना चाहिए)

डेविड वेस्ट द्वारा "ऑब्जेक्ट थिंकिंग" विषय पर पढ़ने के लिए एक अच्छी किताब है।

3

कक्षा के कुछ हर्बीवोर के पास एक खातिर कार्य होगा, जैसा कि कक्षा कार्निवोर की कुछ चीज होगी, लेकिन प्रत्येक के खाने के खाने पर क्या तर्क पारित किया जा सकता है पर कुछ अलग-अलग प्रतिबंध होंगे। फल खाया जाता है, इसलिए इसे Herbivore.Eat() के लिए तर्क के रूप में पारित किया जाएगा, जबकि आप हैम्बर्गर को कार्निवोर के लिए एक वस्तु को पास करना चाहते हैं। ईट(), और हैम्बर्गर पारित होने पर अपवाद उठाएं Herbivore.Eat() के लिए।

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

+0

अच्छा जवाब। ओओपी में नामकरण वर्ग मनुष्यों से परिचित अवधारणाओं का उपयोग करने के बारे में अधिक है। इस तरह कोड मॉड्यूल के व्यवहार को मानना ​​आसान है। मॉडल के मॉडल के आधार पर कार्निवोर के अलग-अलग व्यवहार हो सकते हैं, लेकिन किसी भी मामले में यह ThingThatOnlyEatsMeat कहने से अधिक सहज है। – TheSecretSquad

0

मेरी समझ यह है कि हमारे पास ऑब्जेक्ट्स हैं ताकि हम अपने कार्यक्रमों को वास्तविक जीवन वस्तुओं को दर्पण करने के लिए डिज़ाइन कर सकें।

शायद लागू होने पर वास्तविक जीवन वस्तुओं से उन्हें 'संबंधित' करना पसंद है।

क्या एक फल वस्तु को मानव वस्तु को पारित किया जाना चाहिए जिसमें ईट() फ़ंक्शन है?

हाँ, या मानव से कुछ अधिक सामान्य।

मैं इस बारे में सोचने का सही तरीका जानने का प्रयास कर रहा हूं। सामान्य रूप से, प्रोग्रामिंग ऑब्जेक्ट्स वास्तविक जीवन वस्तुओं को दर्पण करना चाहिए।

केवल परिभाषित करें कि आपको परिभाषित करने की आवश्यकता है। फिर कार्यान्वयन (आमतौर पर) बहुत स्पष्ट हो जाता है। दूसरे शब्दों में, आप शायद बहुत कठिन सोच रहे हैं।

0

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

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