कक्षाओं के साथ OOP की तुलना में कार्यात्मक प्रोग्रामिंग


32

मुझे हाल ही में कार्यात्मक प्रोग्रामिंग की कुछ अवधारणाओं में दिलचस्पी है। मैंने पिछले कुछ समय से OOP का उपयोग किया है। मैं देख सकता हूं कि मैं OOP में एक काफी जटिल ऐप कैसे बनाऊंगा। प्रत्येक वस्तु को पता होता है कि वस्तु को कैसे करना है। या कुछ भी यह माता-पिता वर्ग के रूप में अच्छी तरह से करता है। इसलिए मैं बस Person().speak()व्यक्ति को बात करने के लिए कह सकता हूं ।

लेकिन मैं कार्यात्मक प्रोग्रामिंग में समान चीजें कैसे करूं? मैं देखता हूं कि फ़र्स्ट क्लास आइटम कैसे होते हैं। लेकिन वह कार्य केवल एक विशिष्ट कार्य करता है। क्या मेरे पास बस एक say()तरीका होगा जो इधर-उधर घूमता रहे और उसे Person()तर्क के बराबर कहे, इसलिए मुझे पता है कि किस तरह की बात कह रहा है?

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

संदर्भ के लिए, OOP के साथ मेरा प्राथमिक अनुभव पायथन, पीएचपी और कुछ सी # है। मैं जिन भाषाओं को देख रहा हूं उनमें कार्यात्मक विशेषताएं हैं स्काला और हास्केल। हालांकि मैं स्काला की ओर झुक रहा हूं।

मूल उदाहरण (पायथन):

Animal(object):
    def say(self, what):
        print(what)

Dog(Animal):
    def say(self, what):
        super().say('dog barks: {0}'.format(what))

Cat(Animal):
    def say(self, what):
        super().say('cat meows: {0}'.format(what))

dog = Dog()
cat = Cat()
dog.say('ruff')
cat.say('purr')

स्काला को ओओपी + एफपी के रूप में डिज़ाइन किया गया है, इसलिए आपको चुनने की ज़रूरत नहीं है
कार्तिक टी

1
हां मैं जागरूक हूं, लेकिन मैं बौद्धिक कारणों से भी जानना चाहता हूं। मैं कार्यात्मक भाषाओं में ऑब्जेक्ट के समतुल्य कुछ भी नहीं पा सकता हूं। scala के लिए, मैं अभी भी जानना चाहता हूं कि कब / कहाँ / कैसे मैं oop पर कार्यात्मक का उपयोग करना चाहिए, लेकिन यह कि IMHO एक और प्रश्न है।
भाषा

2
"विशेष रूप से अधिक जोर दिया, IMO यह धारणा है कि हम राज्य को बनाए नहीं रखते हैं।": यह गलत धारणा है। यह सच नहीं है कि एफपी राज्य का उपयोग नहीं करता है, बल्कि एफपी राज्य को अलग तरीके से संभालता है (जैसे हास्केल में मठ या क्लीन में अद्वितीय प्रकार)।
जियोर्जियो


जवाबों:


21

यहाँ आप वास्तव में क्या पूछ रहे हैं कि कार्यात्मक भाषाओं में बहुरूपता कैसे किया जाता है , अर्थात ऐसे कार्यों का निर्माण कैसे किया जाता है जो उनके तर्कों के आधार पर भिन्न व्यवहार करते हैं।

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

सामान्य रूप से कार्यात्मक भाषाएं बहुरूपता को प्राप्त करने के लिए विभिन्न विकल्प प्रदान करती हैं:

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

एक उदाहरण के रूप में, यहां मल्टीमिथोड्स का उपयोग करके आपकी समस्या का क्लोजर कार्यान्वयन है:

;; define a multimethod, that dispatched on the ":type" keyword
(defmulti say :type)  

;; define specific methods for each possible value of :type. You can add more later
(defmethod say :cat [animal what] (println (str "Car purrs: " what)))
(defmethod say :dog [animal what] (println (str "Dog barks: " what)))
(defmethod say :default [animal what] (println (str "Unknown noise: " what)))

(say {:type :dog} "ruff")
=> Dog barks: ruff

(say {:type :ape} "ook")
=> Unknown noise: ook

ध्यान दें कि इस व्यवहार को परिभाषित करने के लिए किसी भी स्पष्ट वर्गों की आवश्यकता नहीं है: नियमित नक्शे ठीक काम करते हैं। प्रेषण समारोह (इस मामले में प्रकार) तर्कों का कोई भी मनमाना कार्य हो सकता है।


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

11

यह प्रत्यक्ष उत्तर नहीं है, और न ही यह आवश्यक रूप से 100% सटीक है क्योंकि मैं एक कार्यात्मक भाषा विशेषज्ञ नहीं हूं। लेकिन किसी भी मामले में, मैं आपके साथ अपना अनुभव साझा करूंगा ...

लगभग एक साल पहले मैं भी आप जैसी ही नाव में था। मैंने C ++ और C # किया है और मेरे सभी डिज़ाइन हमेशा OOP पर बहुत भारी थे। मैंने एफपी भाषाओं के बारे में सुना है, कुछ जानकारी ऑनलाइन पढ़ी है, एफ # पुस्तक के माध्यम से फ़्लिप किया है, लेकिन अभी भी वास्तव में समझ नहीं सका कि एफपी भाषा ओओपी को कैसे बदल सकती है या सामान्य रूप से उपयोगी हो सकती है जैसा कि मैंने देखा है सबसे उदाहरण।

मेरे लिए "सफलता" तब आई जब मैंने अजगर सीखने का फैसला किया। मैंने अजगर को डाउनलोड किया, फिर प्रोजेक्ट यूलर होमपेज पर गया और बस एक के बाद एक समस्याएँ करने लगा। पायथन आवश्यक रूप से एक एफपी भाषा नहीं है और आप निश्चित रूप से इसमें कक्षाएं बना सकते हैं, लेकिन सी ++ / जावा / सी # की तुलना में, इसमें बहुत अधिक एफपी निर्माण है, इसलिए जब मैंने इसके साथ खेलना शुरू किया, तो मैंने एक सचेत निर्णय नहीं लिया। जब तक मैं पूरी तरह से एक वर्ग को परिभाषित नहीं करता।

पायथन के बारे में जो मुझे दिलचस्प लगा वह यह था कि कार्यों को लेना कितना आसान और स्वाभाविक था और अधिक जटिल कार्यों को बनाने के लिए उन्हें "सिलाई" करना और अंत में एकल फ़ंक्शन को कॉल करके आपकी समस्या अभी भी हल हो गई थी।

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

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

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

पिछले हफ्ते मैंने जावा में कोडिंग शुरू की और तब से, लगभग दैनिक आधार पर मुझे याद दिलाया जाता है कि जब ओओपी में, मुझे उन तरीकों के साथ कक्षाओं की घोषणा करके इंटरफेस को लागू करना होगा जो कार्यों को ओवरराइड करते हैं, तो कुछ मामलों में मैं पायथन का उपयोग करके उसी चीज़ को प्राप्त कर सकता हूं। उदाहरण के लिए, साधारण लैंबडा अभिव्यक्ति, कोड की 20-30 पंक्तियाँ जो मैंने किसी निर्देशिका को स्कैन करने के लिए लिखी हैं, पायथन में 1-2 पंक्तियाँ होंगी और कोई कक्षाएं नहीं होंगी।

एफपी खुद उच्च स्तर की भाषाएं हैं। पायथन में (क्षमा करें, मेरा एकमात्र एफपी अनुभव) मैं एक साथ सूची की समझ को एक अन्य सूची के अंदर डाल सकता था, जिसमें लैम्बदास और अन्य सामान फेंके गए थे और पूरी बात केवल कोड की 3-4 पंक्तियों की होगी। C ++ में, मैं एक ही चीज़ को पूरी तरह से पूरा कर सकता था, लेकिन क्योंकि C ++ लो-लेवल है, मुझे 3-4 लाइनों की तुलना में बहुत अधिक कोड लिखना होगा और जैसे-जैसे लाइनों की संख्या बढ़ेगी, मेरा SRP प्रशिक्षण अंदर आएगा और मैं शुरू करूँगा। कोड को छोटे टुकड़ों में विभाजित करने के तरीके के बारे में सोच (यानी अधिक कार्य)। लेकिन कार्यान्वयन विवरणों को बनाए रखने और छिपाने के हितों में, मैं उन सभी कार्यों को एक ही वर्ग में रखूंगा और उन्हें निजी बनाऊंगा। और वहाँ आपके पास है ... मैंने अभी एक वर्ग बनाया है जबकि अजगर में मैंने "वापसी (लैम्ब्डा एक्स: .... ....) लिखा होगा।"


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

बहुत बढ़िया जवाब। मजेदार पूल के किनारे खड़े हर किसी से बात करता है, लेकिन यह सुनिश्चित नहीं करता है कि पानी में अपने पैर की अंगुली को डुबाना है
Robben_Ford_Fan_boy

और रूबी ... एक तर्क के रूप में एक कोड ब्लॉक लेने के तरीकों पर इसके डिजाइन दर्शन केंद्रों में से एक, आमतौर पर एक वैकल्पिक। और स्वच्छ वाक्यविन्यास सोच को देखते हुए और इस तरह से कोडिंग करना आसान है। C # में ऐसा सोचना और रचना करना कठिन है। C # रिट कार्यात्मक रूप से क्रियात्मक और अव्यवस्थित है, यह भाषा में जूता-सा लगता है। मुझे पसंद है कि रूबी ने कार्यात्मक रूप से आसान सोचने में मदद की, मेरे सीडेड सी # विचार बॉक्स में क्षमता देखने के लिए। अंतिम विश्लेषण में मैं कार्यात्मक और OO को पूरक के रूप में देखता हूं; मैं कहता हूं कि रूबी निश्चित रूप से ऐसा सोचती है।
राडार

8

हास्केल में, आपके पास "क्लास" है। यह वर्ग हालांकि जावा और सी ++ में कक्षा के समान नहीं है , आप इस मामले में जो चाहते हैं उसके लिए काम करेंगे।

आपके मामले में यह है कि आपका कोड कैसा दिखेगा।

कक्षा पशु जहां 
कहते हैं :: स्ट्रिंग -> ध्वनि 

फिर आपके पास इन तरीकों को अपनाने के लिए अलग-अलग डेटा प्रकार हो सकते हैं।

उदाहरण पशु कुत्ता जहां
s = "छाल" ++ s 

EDIT: - इससे पहले कि आप डॉग के लिए कह सकें, आपको सिस्टम को यह बताना होगा कि डॉग पशु है।

डेटा डॉग = \ - यहां कुछ - \ (व्युत्पन्न पशु)

EDIT: - विल्क के लिए।
अब यदि आप किसी फ़ंक्शन को फू कहना कहते हैं, तो आपको हैसेल को बताना होगा कि फू केवल एनिमल के साथ काम कर सकता है।

foo :: (पशु a) => a -> स्ट्रिंग -> स्ट्रिंग
foo a str = say a str 

अब अगर तुम कुत्ते के साथ फू को बुलाओ तो वह भौंक जाएगा, अगर तुम बिल्ली से पुकारोगे तो वह म्याऊ करेगा।

मु य = करना 
d = डॉग (\ - क्रस्ट पैरामीटर - \)
    ग = बिल्ली  
शो में $ f d "हैलो वर्ल्ड"

अब आपके पास फ़ंक्शन की कोई अन्य परिभाषा नहीं हो सकती है। यदि कहा जाता है कि ऐसी कोई भी चीज़ है जिसे पशु नहीं कहा जाता है, तो यह संकलन त्रुटि का कारण होगा।


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

nitpick पशु पूंजीकृत किया जाना चाहिए
डैनियल Gratzer

1
उक्त फ़ंक्शन को कैसे पता चलता है कि आप इसे डॉग पर कॉल करते हैं यदि यह केवल एक स्ट्रिंग लेता है? और केवल कुछ अंतर्निहित कक्षाओं के लिए "व्युत्पन्न" नहीं है?
विल्क्यू डेसी

6

बहुरूपता को प्राप्त करने के लिए कार्यात्मक भाषाएं 2 निर्माणों का उपयोग करती हैं:

  • प्रथम कार्य
  • जेनेरिक्स

उन लोगों के साथ बहुरूपी कोड बनाना पूरी तरह से अलग है कि OOP विरासत और आभासी तरीकों का उपयोग कैसे करते हैं। जबकि वे दोनों आपकी पसंदीदा ओओपी भाषा (जैसे सी #) में उपलब्ध हो सकते हैं, अधिकांश कार्यात्मक भाषाएं (जैसे हास्केल) इसे ग्यारह तक मारती हैं। गैर-जेनेरिक होने के लिए कार्य करना दुर्लभ है और अधिकांश कार्यों में पैरामीटर के रूप में कार्य होते हैं।

इस तरह की व्याख्या करना कठिन है और इस नए तरीके को सीखने के लिए आपके समय की बहुत आवश्यकता होगी। लेकिन ऐसा करने के लिए, आपको ओओपी को पूरी तरह से भूल जाने की आवश्यकता है, क्योंकि यह नहीं है कि यह कार्यात्मक दुनिया में कैसे काम करता है।


2
ओओपी सभी बहुरूपता के बारे में है। अगर आपको लगता है कि OOP आपके डेटा से जुड़े कार्य करता है, तो आप OOP के बारे में कुछ नहीं जानते हैं।
व्यंग्यात्मक

4
बहुरूपता ओओपी का सिर्फ एक पहलू है, और मुझे लगता है कि ओपी वास्तव में इसके बारे में नहीं पूछ रहा है।
डॉक्टर ब्राउन

2
बहुरूपता OOP का प्रमुख पहलू है। इसका समर्थन करने के लिए बाकी सब कुछ है। विरासत / आभासी तरीकों के बिना OOP प्रक्रियात्मक प्रोग्रामिंग के लगभग समान है।
व्यंग्यात्मक

1
@ ErikReppen यदि "एक इंटरफ़ेस लागू करें" की आवश्यकता अक्सर नहीं होती है, तो आप OOP नहीं कर रहे हैं। साथ ही हास्केल में मॉड्यूल भी हैं।
व्यंग्यात्मक

1
आपको हमेशा एक इंटरफ़ेस की आवश्यकता नहीं होती है। लेकिन वे अत्यधिक उपयोगी होते हैं जब आपको उनकी आवश्यकता होती है। और IMO OOP का एक और महत्वपूर्ण हिस्सा है। जैसा कि मॉड्यूल हास्केल में जाता है, मुझे लगता है कि यह संभवतः कार्यात्मक भाषाओं के लिए OOP के सबसे करीब है, जहां तक ​​कोड संगठन का संबंध है। कम से कम जो मैंने अभी तक पढ़ा है। मुझे पता है कि वे अभी भी बहुत अलग हैं।
भाषा

0

यह वास्तव में इस बात पर निर्भर करता है कि आप क्या हासिल करना चाहते हैं।

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

def bark(what):
    print "barks: {0}".format(what) 

def meow(what):
    print "meows: {0}".format(what)

def climb(how):
    print "climbs: {0}".format(how)

if __name__ == "__main__":
    animals = {'dog': {'say': bark},
               'cat': {'say': meow,
                       'climb': climb}}
    animals['dog']['say']("ruff")
    animals['cat']['say']("purr")
    animals['cat']['climb']("well")

हालाँकि, ध्यान दें कि (ए) कुत्ते या बिल्ली के कोई 'उदाहरण' नहीं हैं और (बी) आपको खुद अपनी वस्तुओं के 'प्रकार' का ट्रैक रखना होगा।

उदाहरण के लिए की तरह है: pets = [['martin','dog','grrrh'], ['martha', 'cat', 'zzzz']]। तो आप की तरह एक सूची समझ कर सकता है[animals[pet[1]]['say'](pet[2]) for pet in pets]


0

कभी-कभी मशीन के साथ सीधे इंटरफ़ेस करने के लिए निम्न-स्तरीय भाषाओं के स्थान पर OO भाषाओं का उपयोग किया जा सकता है। C ++ सुनिश्चित करने के लिए, लेकिन यहां तक ​​कि C # के लिए भी एडेप्टर और ऐसे हैं। यद्यपि यांत्रिक भागों को नियंत्रित करने के लिए कोड लिखना और स्मृति पर मिनट नियंत्रण रखना सबसे अच्छा संभव के रूप में निम्न-स्तर के करीब रखा जाता है। लेकिन अगर यह प्रश्न वर्तमान ऑब्जेक्ट-ओरिएंटेड सॉफ़्टवेयर जैसे लाइन ऑफ़ बिज़नेस, वेब एप्लिकेशन, IOT, वेब सर्विसेज और बहुसंख्यक उपयोग किए गए अनुप्रयोगों से संबंधित है, तो ...

उत्तर, यदि लागू हो

पाठक एक सेवा-उन्मुख वास्तुकला (SOA) के साथ काम करने की कोशिश कर सकते हैं। यानी, DDD, N- लेयर्ड, N-Tiered, Hexagonal, जो भी हो। मैंने एक बड़े व्यावसायिक अनुप्रयोग को कुशलतापूर्वक "पारंपरिक" OO (सक्रिय-रिकॉर्ड या रिच-मॉडल) का उपयोग नहीं देखा है क्योंकि यह पिछले दशक में 70 और 80 के बहुत अधिक वर्णन किया गया था। (नोट 1 देखें)

गलती ओपी के साथ नहीं है, लेकिन सवाल के साथ कुछ समस्याएं हैं।

  1. उदाहरण आप प्रदान करते हैं बस बहुरूपता प्रदर्शित करने के लिए, यह उत्पादन कोड नहीं है। कभी-कभी उदाहरण बिल्कुल वैसा ही होता है जैसा कि शब्दशः लिया जाता है।

  2. FP और SOA में, डेटा को बिजनेस लॉजिक से अलग किया जाता है। यानी डेटा और लॉजिक एक साथ नहीं चलते। तर्क सेवाओं में चला जाता है, और डेटा (डोमेन मॉडल) में पॉलीमॉर्फिक व्यवहार नहीं होता है (नोट 2 देखें)।

  3. सेवाएँ और कार्य बहुरूपी हो सकते हैं। एफपी में, आप अक्सर मानों के बजाय अन्य कार्यों के मापदंडों के रूप में कार्य करते हैं। आप OO भाषाओं में Callable या Func जैसे प्रकारों के साथ कर सकते हैं, लेकिन यह बड़े पैमाने पर नहीं चलता है (नोट 3 देखें)। FP और SOA में, आपके मॉडल केवल आपकी सेवाएँ / कार्य पॉलिमॉर्फिक नहीं हैं। (नोट 4 देखें)

  4. उस उदाहरण में हार्डकोडिंग का एक बुरा मामला है। मैं न केवल लाल रंग के स्ट्रिंग "कुत्ते के छाल" के बारे में बात कर रहा हूं। मैं खुद CatModel और DogModel के बारे में भी बात कर रहा हूं। जब आप एक भेड़ जोड़ना चाहते हैं तो क्या होता है? आपको अपने कोड में जाना होगा और नया कोड बनाना होगा? क्यूं कर? उत्पादन कोड में, मैं इसके गुणों के साथ सिर्फ एक AnimalModel देखना चाहूंगा। सबसे कम, एक AmphibianModel और एक FowlModel अगर उनके गुण और हैंडलिंग अलग हैं।

यह वह है जो मैं एक "ओओ" भाषा में देखने की उम्मीद करूंगा:

public class Animal
{
    public int AnimalID { get; set; }
    public int LegCount { get; set; }
    public string Name { get; set; }
    public string WhatISay { get; set; }
}

public class AnimalService : IManageAnimals
{
    private IPersistAnimals _animalRepo;
    public AnimalService(IPersistAnimals animalRepo) { _animalRepo = animalRepo; }

    public List<Animal> GetAnimals() => _animalRepo.GetAnimals();

    public string WhatDoISay(Animal animal)
    {
        if (!string.IsNullOrWhiteSpace(animal.WhatISay))
            return animal.WhatISay;

        return _animalRepo.GetAnimalNoise(animal.AnimalID);
    }
}

मूल प्रवाह

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

OO भाषा FP के करीब एक कदम है

आप इसे थोड़ा और आगे ले जा सकते हैं और अपनी SOA सेवाओं को दो प्रकारों में विभाजित कर सकते हैं।

वैकल्पिक कक्षा प्रकार 1 : प्रवेश बिंदुओं के लिए सामान्य इंटरफ़ेस-कार्यान्वयन सेवाएँ। ये एंट्री-पॉइंट "अशुद्ध" होंगे जो "शुद्ध" या "इंप्रूव" अन्य कार्यक्षमता में कॉल कर सकते हैं। यह आपके RESTful API से एंट्री पॉइंट हो सकता है।

वैकल्पिक क्लास टाइप 2 : प्योर बिजनेस लॉजिक सर्विसेज। ये स्टैटिक क्लास हैं जिनकी "शुद्ध" कार्यक्षमता है। एफपी में, "शुद्ध" का मतलब है कि कोई दुष्प्रभाव नहीं हैं। यह स्पष्ट रूप से राज्य या दृढ़ता को कहीं भी निर्धारित नहीं करता है। (नोट 5 देखें)

इसलिए जब आप ऑब्जेक्ट-ओरिएंटेड लैंग्वेजेज में क्लासेस के बारे में सोचते हैं, तो एक सर्विस-ओरिएंटेड आर्किटेक्चर में इस्तेमाल होने के कारण, यह न केवल आपके OO कोड को फायदा पहुंचाता है, यह फंक्शनल प्रोग्रामिंग को समझने में बहुत आसान लगता है।

टिप्पणियाँ

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

नोट 2 : डोमेन मॉडल में पॉलीमॉर्फिक व्यवहार नहीं है, न ही उनके पास बाहरी निर्भरता है। वे "पृथक" हैं। इसका मतलब यह नहीं है कि उन्हें 100% एनीमिक होना चाहिए। उनके निर्माण और उत्परिवर्तनीय संपत्ति परिवर्तन से संबंधित बहुत सारे तर्क हो सकते हैं, अगर ऐसा लागू होता है। डीडीडी "मूल्य वस्तुओं" और एरिक इवांस और मार्क सीमन द्वारा एंटिटीज देखें।

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

नोट 4 : वंशानुक्रम के साथ बहुरूपता को भ्रमित नहीं करना। एक कैटमॉडल एनिमलबेस को इनहेरिट करने के लिए निर्धारित कर सकती है कि कौन से गुण एक जानवर के पास हैं। लेकिन जैसा कि मैं दिखाता हूं, इस तरह के मॉडल एक कोड गंध हैं । यदि आप इस पैटर्न को देखते हैं, तो आप इसे तोड़ने और इसे डेटा में बदलने पर विचार कर सकते हैं।

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


-2

आप ऐसा कुछ कर सकते हैं .. php

    function say($whostosay)
    {
        if($whostosay == 'cat')
        {
             return 'purr';
        }elseif($whostosay == 'dog'){
             return 'bark';
        }else{
             //do something with errors....
        }
     }

     function speak($whostosay)
     {
          return $whostosay .'\'s '.say($whostosay);
     }
     echo speak('cat');
     >>>cat's purr
     echo speak('dog');
     >>>dogs's bark

1
मैंने कोई नकारात्मक वोट नहीं दिया है। लेकिन मेरा अनुमान है कि ऐसा इसलिए है क्योंकि यह दृष्टिकोण न तो कार्यात्मक है न ही वस्तु उन्मुख।
मनोज आर

1
लेकिन व्यक्त की गई अवधारणा कार्यात्मक प्रोग्रामिंग में प्रयुक्त पैटर्न मिलान के करीब है, अर्थात $whostosayऑब्जेक्ट प्रकार बन जाता है जो निर्धारित करता है कि क्या निष्पादित होता है। उपरोक्त को किसी अन्य पैरामीटर को अतिरिक्त रूप से स्वीकार करने के लिए संशोधित किया जा सकता है $whattosayताकि एक प्रकार जो इसका समर्थन करता है (जैसे 'human') इसका उपयोग कर सके।
syockit
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.