एनीमिक डोमेन मॉडल को C # / OOP में बुरा क्यों माना जाता है, लेकिन F # / FP में बहुत महत्वपूर्ण है?


46

मस्ती और लाभ के लिए एफ # पर एक ब्लॉग पोस्ट में , यह कहता है:

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

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

वास्तव में, OOD में, डेटा प्रकार के आस-पास पर्याप्त व्यवहार नहीं होने को एक बैड थिंग माना जाता है, और यहां तक ​​कि एक नाम भी है: " एनीमिक डोमेन मॉडल "।

यह देखते हुए कि C # में हम F # से उधार लेते रहते हैं, और अधिक कार्यात्मक-शैली कोड लिखने की कोशिश कर रहे हैं; कैसे हम डेटा / व्यवहार को अलग करने के विचार को उधार नहीं ले रहे हैं, और यहां तक ​​कि इसे बुरा मानते हैं? क्या यह केवल यह है कि परिभाषा OOP के साथ नहीं है, या कोई ठोस कारण है कि यह C # में खराब है कि किसी कारण से F # में लागू नहीं होता है (और वास्तव में, उलट है)?

(नोट: मैं विशेष रूप से C # / F # में मतभेदों में दिलचस्पी रखता हूं जो कि उन लोगों के बजाय जो अच्छे / बुरे हैं, उनकी राय को बदल सकते हैं, जो ब्लॉग पोस्ट में किसी भी राय से असहमत हो सकते हैं)।


1
हाय दान! आपका पालन प्रेरणादायी है। .NET (और हैसेल) प्लेटफॉर्म के अलावा मैं आपको स्कैला को देखने के लिए प्रोत्साहित करता हूं। देबाशीष घोष ने कार्यात्मक उपकरणों के साथ डोमेन मॉडलिंग के बारे में ब्लॉगों के एक जोड़े को लिखा है, यह मेरे लिए बहुत ही सुखद
AndreasScheinz

2
मुझे आज एक सहकर्मी द्वारा एक दिलचस्प ब्लॉग पोस्ट भेजा गया: blog.inf.ed.ac.uk/sapm/2014/02/04// ऐसा लगता है कि लोग इस विचार को चुनौती देना शुरू कर रहे हैं कि एनीमिक डोमेन मॉडल एकमुश्त खराब हैं; जो मुझे लगता है कि एक अच्छी बात हो सकती है!
डैनी टुप्पेनी

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

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

2
@ जिमीहॉफ मैं सहमत हूं, लेकिन इसका मेरी आलोचना के साथ कोई लेना-देना नहीं है। लेखक का दावा है कि डेटा के लिए यह सामान्य रूप से ठीक है क्योंकि यह अपरिवर्तनीय है, और मैं कह रहा हूं कि अपरिवर्तनीयता जादुई रूप से कार्यान्वयन विवरण को छिपाने की आवश्यकता को दूर नहीं करती है।
डोभाल

जवाबों:


37

एफपी का मुख्य कारण यह है और सी # ओओपी यह नहीं है कि एफपी में ध्यान केंद्रित करने के लिए प्रासंगिक पारदर्शिता है; यही है, डेटा एक फ़ंक्शन में जाता है और डेटा बाहर आता है, लेकिन मूल डेटा नहीं बदला गया है।

C # OOP में जिम्मेदारी के प्रत्यायोजन की एक अवधारणा है जहाँ आप किसी वस्तु के प्रबंधन को उसमें सौंपते हैं, और इसलिए आप चाहते हैं कि यह अपने स्वयं के आंतरिक को बदल दे।

FP में आप कभी भी ऑब्जेक्ट में वैल्यूज़ नहीं बदलना चाहते हैं, इसलिए आपके फ़ंक्शंस आपके ऑब्जेक्ट में एम्बेडेड होने का कोई मतलब नहीं है।

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

C # OOP में एनीमिक डोमेन मॉडल में मैंने जो सबसे बड़ी समस्या देखी है, वह यह है कि आप डुप्लिकेट कोड के साथ समाप्त होते हैं क्योंकि आपके पास DTO x, और 4 अलग-अलग फ़ंक्शंस हैं जो गतिविधि को DTO x तक ले जाते हैं क्योंकि 4 अलग-अलग लोगों ने अन्य कार्यान्वयन नहीं देखा था । जब आप सीधे डीटीओ एक्स पर विधि डालते हैं, तो वे 4 लोग सभी एफ के कार्यान्वयन को देखते हैं और इसका पुन: उपयोग करते हैं।

C # OOP बाधा कोड पुन: उपयोग में एनीमिक डेटा मॉडल, लेकिन यह FP में ऐसा नहीं है क्योंकि एक ही फ़ंक्शन को कई अलग-अलग प्रकारों में सामान्यीकृत किया जाता है ताकि आपको अधिक से अधिक कोड पुन: उपयोग मिल जाए क्योंकि उस फ़ंक्शन को फ़ंक्शन की तुलना में इतने अधिक परिदृश्यों में उपयोग करने योग्य है C # में एक एकल DTO के लिए लिखेगा।


जैसा कि टिप्पणियों में बताया गया है , इस तरह के महत्वपूर्ण बहुरूपता की अनुमति देने के लिए एफपी एक प्रकार का लाभ है, जो एफपी पर निर्भर करता है, और विशेष रूप से आप इसे एल्गोरिथ्म डब्ल्यू प्रकार के निष्कर्ष के साथ हिंडले मिलनर प्रकार प्रणाली में वापस पा सकते हैं; सी # ओओपी प्रकार प्रणाली में इस तरह के आक्षेप को टाला गया क्योंकि संकलन का समय जब थकावट आधारित खोज को जोड़ा जाता है, तो संपूर्ण खोज आवश्यक होने के कारण यह बहुत लंबा हो जाता है, यहां विवरण: https://stackoverflow.com/questions/3958834/generics-why -cant-संकलक अनुमान-प्रकार-तर्क-इन-इस दर-मामला


F # में कौन सी सुविधा है, जिससे इस प्रकार के पुन: प्रयोज्य कोड को लिखना आसान हो जाता है? C # में कोड पुन: प्रयोज्य क्यों नहीं हो सकता है? (मुझे लगता है कि मैंने तरीकों को विशिष्ट गुणों के साथ तर्क देने की क्षमता देखी, बिना किसी इंटरफ़ेस की आवश्यकता के; जो मुझे लगता है कि एक महत्वपूर्ण होगा?)
डैनी टुप्पेनी

7
@DannyTuppeny ईमानदारी से एफ # तुलना करने के लिए एक खराब उदाहरण है, यह सिर्फ एक थोड़ा सी # तैयार है; यह C # की तरह ही एक परिवर्तनशील अनिवार्य भाषा है, इसमें कुछ FP सुविधाएं हैं जो C # के पास नहीं हैं लेकिन बहुत ज्यादा नहीं हैं। यह देखने के लिए कि क्या FP वास्तव में बाहर खड़ा है और इस तरह की चीजें टाइप कक्षाओं के साथ-साथ सामान्य ADTs
जिमी हॉफ

@MattFenwick मैं स्पष्ट रूप से C # का उल्लेख कर रहा हूं, क्योंकि पोस्टर के बारे में यही पूछ रहा था। जहाँ मैं अपने उत्तर में OOP का उल्लेख करता हूँ यहाँ मेरा मतलब है C # OOP, मैं स्पष्ट करने के लिए संपादित करूँगा।
जिमी हॉफ

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

4
@KeithS हास्केल में मूल्य आधारित ओवरलोडिंग से मुझे लगता है कि आप पैटर्न से मेल खाते हैं। हास्केल के विभिन्न पैटर्न डेजुगर्स के साथ एक ही नाम के कई शीर्ष स्तर के कार्य करने के लिए तुरंत 1 tovelvel फ़ंक्शन + एक पैटर्न मैच।
जोज़फग

6

एनीमिक डोमेन मॉडल को C # / OOP में बुरा क्यों माना जाता है, लेकिन F # / FP में बहुत महत्वपूर्ण है?

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

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

कैसे हम डेटा / व्यवहार को अलग करने के विचार को उधार नहीं ले रहे हैं, और यहां तक ​​कि इसे बुरा मानते हैं?

जेनरिक को डेटा और व्यवहार को अलग करने का एक तरीका माना जा सकता है। कार्यात्मक प्रोग्रामिंग भाषाओं के एमएल परिवार से आने वाली पीढ़ी ओओपी का हिस्सा नहीं है। C # में जरनल है। तो कोई यह तर्क दे सकता है कि C # डेटा और व्यवहार को अलग करने के विचार को धीरे-धीरे उधार ले रहा है।

क्या यह बस इतना है कि परिभाषा OOP के साथ फिट नहीं है,

मेरा मानना ​​है कि OOP एक मौलिक रूप से अलग आधार पर आधारित है और इसके परिणामस्वरूप, आपको वे उपकरण नहीं दिए जाते हैं जिनकी आपको डेटा और व्यवहार को अलग करने की आवश्यकता होती है। सभी व्यावहारिक उद्देश्यों के लिए आपको उत्पाद और योग डेटा की आवश्यकता है और उन पर प्रेषण। एमएल में इसका मतलब संघ और रिकॉर्ड प्रकार और पैटर्न मिलान है।

की जाँच करें उदाहरण मैं यहाँ दे दी है

या वहाँ एक ठोस कारण है कि यह C # में खराब है कि किसी कारण से F # में लागू नहीं होता है (और वास्तव में, उलट है)?

OOP से C # कूदने के बारे में सावधान रहें। C # अन्य भाषाओं की तरह OOP के बारे में शुद्धतावादी नहीं है। .NET फ्रेमवर्क अब जेनरिक, स्टैटिक तरीकों और यहां तक ​​कि लैम्ब्डा से भरा है।

(नोट: मैं विशेष रूप से C # / F # में मतभेदों में दिलचस्पी रखता हूं जो कि उन लोगों के बजाय जो अच्छे / बुरे हैं, उनकी राय को बदल सकते हैं, जो ब्लॉग पोस्ट में किसी भी राय से असहमत हो सकते हैं)।

C # में यूनियन प्रकार और पैटर्न मिलान की कमी से ऐसा करना लगभग असंभव हो जाता है। जब आपके पास एक हथौड़ा है, तो सब कुछ एक नाखून की तरह दिखता है ...


2
... जब आपके पास एक हथौड़ा होता है, तो OOP लोक हथौड़ा कारखानों का निर्माण करेगा; पी +1 वास्तव में क्या सी # के क्रंदन को कम करने के लिए डेटा और व्यवहार को प्रत्येक अभिभावक से पूरी तरह से सार करने की अनुमति देने के लिए गायब है: यूनियन प्रकार और पैटर्न मिलान।
जिमी हॉफ

-4

मुझे लगता है कि एक व्यावसायिक अनुप्रयोग में आप अक्सर डेटा छिपाना नहीं चाहते हैं क्योंकि अपरिवर्तनीय मूल्यों पर मिलान पैटर्न यह सुनिश्चित करने के लिए बहुत अच्छा है कि आप सभी संभावित मामलों को कवर कर रहे हैं। लेकिन अगर आप जटिल एल्गोरिदम या डेटा संरचनाओं को लागू कर रहे हैं, तो आप ADT (बीजीय डेटा प्रकार) को ADT (अमूर्त डेटा प्रकार) में बदलकर कार्यान्वयन विवरणों को बेहतर ढंग से छिपा सकते हैं।


4
क्या आप इस बारे में थोड़ा और समझा सकते हैं कि यह वस्तुपरक प्रोग्रामिंग बनाम कार्यात्मक प्रोग्रामिंग पर कैसे लागू होता है?
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.