14

कार्यात्मक प्रोग्रामिंग अपरिवर्तनीय कक्षाओं और संदर्भित पारदर्शिता को बढ़ावा देता है।कार्यात्मक प्रोग्रामिंग + डोमेन-संचालित डिजाइन

डोमेन-संचालित डिज़ाइन वैल्यू ऑब्जेक्ट (अपरिवर्तनीय) और संस्थाओं (उत्परिवर्तनीय) से बना है।

क्या हमें उत्परिवर्तनीय लोगों के बजाय अपरिवर्तनीय संस्थाएं बनाना चाहिए?

परियोजना मुख्य भाषा के रूप स्काला का उपयोग करता है के मान लेते हैं,, हम कैसे बासी स्थिति खतरे में डालकर अगर हम संगामिति साथ काम कर रहे बिना के रूप में मामले कक्षाएं (ताकि अपरिवर्तनीय) संस्थाओं लिख सकता है?

एक अच्छा अभ्यास क्या है? इकाइयों को व्यवहार्य रखने (var फ़ील्ड इत्यादि ...) और केस कक्षा के महान वाक्यविन्यास से परहेज करते हुए?

+1

आपको घटना सोर्सिंग इमो में देखना चाहिए, यह ओओपी के साथ डीडीडी के समान दृष्टिकोण प्राप्त करने का एक अच्छा तरीका है। –

+1

https://www.manning.com/books/functional-and-reactive-domain-modeling पर एक नज़र डालें जो डीडीडी और एफपी को गठबंधन करने के तरीके को कवर करता है। देबाशीश में कुछ अच्छी प्रस्तुतियां भी हैं, उदाहरण के लिए: https://www.youtube.com/watch?v=U0Rk9Knq8Vk – Cal

उत्तर

12

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

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

आप दो वैध दृष्टिकोण है:

  • आप तरीकों कि एक आंतरिक संपत्ति संशोधित कर सकते हैं बेनकाब और आप उन तरीकों पर संगामिति प्रबंधन (बहुत कुछ है, वास्तव में)

  • आप सभी वर्ग बनाने अपरिवर्तनीय और आप इसे "प्रबंधक" से घिराते हैं जो खाता बदल सकता है।

चूंकि पहला बहुत सरल है, मैं पहले विवरण दूंगा।

case class BankAccount(val balance:Double, val code:Int) 

class BankAccountRef(private var bankAccount:BankAccount){ 
    def withdraw(withdrawal) = { 
     bankAccount = bankAccount.copy(balance = bankAccount.balance - withdrawal) 
     bankAccount.balance 
    } 
} 

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

संगामिति करने का इष्टतम तरीका: संदेश गुजर

क्या होगा अगर दूसरी तरफ, विभिन्न नौकरियों तरीकों सीधे BankAccount या एक BankAccountRef पर आह्वान नहीं कर सकते हैं, लेकिन सिर्फ उन्हें सूचित कि कुछ कार्यों की जरूरत है प्रदर्शन किया? खैर, तो आपके पास एक अभिनेता है, जो स्कैला में समवर्ती करने का पसंदीदा तरीका है।

class BankAccountActor(private var bankAccount:BankAccount) extends Actor { 

    def receive { 
     case BalanceRequest => sender ! Balance(bankAccount.balance) 
     case Withdraw(amount) => { 
      this.bankAccount = bankAccount.copy(balance = bankAccount.balance - amount) 
     } 
     case Deposit(amount) => { 
      this.bankAccount = bankAccount.copy(balance = bankAccount.balance + amount) 

     } 

    } 
} 

यह समाधान बड़े पैमाने पर अक्का दस्तावेज में वर्णित है: http://doc.akka.io/docs/akka/2.1.0/scala/actors.html। विचार यह है कि आप अपने मेलबॉक्स में संदेश भेजकर एक अभिनेता के साथ संवाद करते हैं, और उन संदेशों को रिसीवल के क्रम में संसाधित किया जाता है। इस तरह, इस मॉडल का उपयोग करते समय आपको कभी भी सहमति नहीं होगी।

+0

लेकिन क्या वर्तमान में स्मृति में परिवर्तन का एक सेट होने का जोखिम नहीं है? आइए कल्पना करें कि कई पृष्ठभूमि नौकरी कार्यों के लिए अलग-अलग धागे एक ही इकाई के विभिन्न संस्करणों को बनाए रखते हैं। यह असंगतता का कारण बन जाएगा, है ना? – Mik378

+0

मैं समझता हूं कि आप कहां से आ रहे हैं। राज्य को बनाए रखने वाली पृष्ठभूमि नौकरियां समस्याओं का स्रोत हो सकती हैं। मुझे अभी भी आश्चर्य है कि स्वतंत्र पृष्ठभूमि नौकरियों – Edmondo1984

+2

उपयोग-मामले के बीच साझा स्थिति को बनाए रखने के लिए कौन सा उपयोग केस वैध है? बैंक खाते। पृष्ठभूमि नौकरियां रिपोर्टिंग, एटीएम-हैंडलर, ब्याज दर-कैलक्यूलेटर ... –

10

यह एक राय प्रश्न है जो आपको लगता है कि कम स्केल विशिष्ट है।

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

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

यह भी निर्भर करता है कि आपका डोमेन क्या है। ओओपी यूआई और वीडियो गेम जैसी राज्यिक चीजों के साथ कुछ बार आसान है। वेब साइट या आरईएसटी जैसी हार्ड कोर बैकएंड सेवाओं के लिए मुझे लगता है कि सेवा पैटर्न बेहतर है।

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

एफपी लोगों में

इसके अलावा एक 'भाषा' या डीएसएल उर्फ ​​"संवाद" (Builders, monads, पाइप्स, तीर, STM आदि ...) है कि आप उत्परिवर्तित लिए सक्षम बनाता है बनाने के द्वारा अपरिवर्तनीय पुल करने के लिए परिवर्तनशील मुकाबला और फिर बदलने के लिए अपरिवर्तनीय डोमेन पर वापस। ऊपर उल्लिखित सेवाएं परिवर्तन करने के लिए डीएसएल का उपयोग करती हैं। यह आपके विचार से अधिक प्राकृतिक है (उदा। एसक्यूएल एक उदाहरण है "संवाद")। दूसरी तरफ ओओपी एक परिवर्तनीय डोमेन और भाषा के मौजूदा प्रक्रियात्मक हिस्से का लाभ उठाने पसंद करता है।

+0

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

+0

@ एडम जेन ग्रेट उत्तर :) – Mik378

+0

@ ब्रायनस्मिथ येप। मुझे लगता है कि डीडीडी के साथ-साथ कुछ अन्य फाउलर/इवांस पैटर्न ओवररेटेड हैं (उन लोगों को एफपी शिविर में कुछ समय बिताने की जरूरत है)। आधुनिक बैकएंड वेब एप्लिकेशन एफपी के साथ बेहतर फिट बैठता है। [मैं भी जावा प्रोग्रामर हूं और इसे पसंद करता हूं] (https://github.com/agentgt/jirm)। डीडीडी की परिभाषा भी फ्लेकी है। और ऐसा लगता है कि डीडीडी ट्रांसफॉर्मेशन उर्फ ​​डीटीओ को तुच्छ मानता है लेकिन मेरे अनुभव में आप हमेशा स्थानांतरण वस्तुओं (यानी अलग-अलग विचार) की आवश्यकता को समाप्त करते हैं। एफपी परिवर्तनों को गले लगाता है। –

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