2016-07-21 5 views
7

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

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

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

सभी उन एफपी पर अशुद्ध कार्यों होगा:

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

बहुत कुछ स्थानों पर, जिसमें मैं डेटा की प्रक्रिया करने के लिए है रहे हैं और उन पुन: प्राप्त करने के कुछ Struct के डेटाबेस से लगभग हमेशा से मिलकर बनता है और एक अन्य Struct कि देखें नियंत्रक (है कि 5 की तरह है द्वारा उपयोग किया जाएगा में कई जानकारी श्रृंखलाबद्ध लाइनें ... मानते हैं कि आपको दृश्य में प्रदर्शित होने के लिए 5 गुणों की आवश्यकता है)। निश्चित रूप से, आपको कुछ प्रसंस्करण करने की आवश्यकता हो सकती है जैसे money: Int = 20 to moneyString: String = "US$\(money).00", लेकिन यह है।

मुझे लगता है कि मैं अपने ऐप विकास चक्र में एफपी लागू करने में विफल रहा हूं। क्या कोई यह स्पष्ट कर सकता है कि मैं इसे कैसे प्राप्त कर सकता हूं? उदाहरण के साथ शायद।

धन्यवाद।

संपादित करें: अभी, निम्नलिखित Clean Architecture विचार, मैं अपने वास्तुकला के रूप में कुछ इस तरह है:

enter image description here

इनपुट View से आ सकता है, कोई बटन क्लिक, वे करने के लिए जाना ViewController जो कॉल करने के लिए Interactor का निर्णय लेता है। Interactor कुछ डेटा प्राप्त करने और इसे वर्तमान डेटा में बदलने के लिए आवश्यक Gateway एस तक पहुंच जाएगा जो Presenter (एक प्रतिनिधि के रूप में) में पारित किया जाएगा। अंत में Presenter नया डेटा प्रदर्शित करने के लिए View अपडेट करेगा।

इसके अतिरिक्त, इनपुट External स्रोतों से आ सकता है, जैसे सर्वर आपको कुछ डेटा अपडेट कर रहा है और आपको View रीफ्रेश करना होगा। यह Interactor (पर्यवेक्षक के रूप में) पर जाता है जो पिछले उदाहरण के अनुसार शेष श्रृंखला का पालन करेगा।

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

+0

@ सैमी कुहमोमन मैंने अपने प्रश्न को और अधिक विशिष्ट होने के लिए अपडेट किया। –

+0

@ Paulw11 मैंने अपने प्रश्न को और अधिक विशिष्ट होने के लिए अपडेट किया। –

+0

@dfri मैंने अपने प्रश्न को और अधिक विशिष्ट होने के लिए अपडेट किया। –

उत्तर

0

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

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

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

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

मॉडल के भीतर, गणना की गई संपत्तियां एफपी द्वारा पालन करने में यह सुनिश्चित करने में एक लंबा सफर तय कर सकती हैं।

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

+0

मैं UITableViewController में डुप्लीकेट ट्रांसफॉर्म किए गए डेटा को कैसे हटाऊंगा? मुझे अपने डेटा स्रोत विधियों में उपयोग करने के लिए वहां एक सरणी चाहिए। –

+0

मैंने अपने वास्तुकला का एक और ठोस उदाहरण जोड़ने के लिए अपना प्रश्न अपडेट कर लिया है। –

0

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

एक आवेदन के लिए, जैसा कि एलन ने कहा था, आपको राज्य के साथ काम करना होगा। आप एफपी डिज़ाइन पैटर्न को कैसे लागू कर सकते हैं, इस बारे में एफपी डिज़ाइन पैटर्न लागू कर सकते हैं, लेकिन इस पर ध्यान दिए बिना, आपको एक बिंदु या दूसरे पर राज्य को संशोधित करना होगा, जैसा कि आपने पाया है, शुद्ध एफपी के साथ गठबंधन नहीं है।

एफपी प्रोग्रामिंग पैटर्न के आपके उपकरण की छाती में एक उपकरण है, लेकिन यह एकमात्र उपकरण नहीं है।

+1

मुझे ठीक है मेरी दृश्य परत (दृश्य और दृश्य नियंत्रक) में स्थिति है, लेकिन ऐसा लगता है कि मेरा अधिकांश एप्लिकेशन बस जानकारी पास कर रहा है, इसलिए मेरी समस्या साइड इफेक्ट्स के साथ है, जैसे डेटाबेस से पढ़ने में। क्या मैं अपने कोड के कुछ हिस्से को विभाजित नहीं कर रहा हूं जो मेरे व्यू कंट्रोलर के समान स्थान पर नहीं जाना चाहिए? –

+0

मैंने अपने वास्तुकला का एक और ठोस उदाहरण जोड़ने के लिए अपना प्रश्न अपडेट कर लिया है। –

2

एक पल के लिए एफपी को अलग करना, बहु-उपयोगकर्ता या समय पर निर्भर मॉडल के साथ चुनौती यह है कि कार्यक्रम के सामने अंत उपयोगकर्ता नियंत्रण घटनाओं का एकमात्र स्रोत नहीं है।

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

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

उस परिपूर्ण दुनिया में, डेटा प्राप्त करने के लिए उपयोगकर्ता की कार्रवाई को पहले स्तर पर कब्जा कर लिया जाएगा और फिर परतों को ले जाया जाएगा।

यह हमें बताता है कि अधिसूचनाओं को व्यू कंट्रोलर द्वारा नियंत्रित किया जाना चाहिए या फिर उन्हें प्राप्त करने के लिए डिज़ाइन किए गए दृश्य घटक द्वारा बेहतर किया जाना चाहिए। ऐसी अधिसूचनाओं में हालांकि किसी भी डेटा को शामिल नहीं किया जाएगा, सिवाय इसके कि मॉडल के किस हिस्से को अवैध किया गया है।

एफपी पर वापस, यह निश्चित रूप से एक विशाल दुष्प्रभाव है यदि आप मानते हैं कि उसके बाद सभी फ़ंक्शन कॉल संभावित रूप से अलग-अलग परिणाम लौटाएंगे। लेकिन ...

गणित में, यदि आप एक फ़ंक्शन को परिभाषित करते हैं जो आपको दूरी पर यात्रा की दूरी देता है लेकिन समय पैरामीटर की आपूर्ति नहीं करता है, तो आप दुष्प्रभाव का शिकार नहीं हैं, आप केवल एक प्रदान करना भूल गए हैं इनपुट मूल्य

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

यदि डेटाबेस किसी भी समय अपने राज्यों के स्नैपशॉट का 100% पूरा सेट रख सकता है तो समय को ठंडा करके या पैरामीटर बनाकर अनुप्रयोगों के शुद्ध एफपी अनुरूपता को मान्य करना संभव होगा।

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

फिर भी, मैं सुझाव दूंगा कि आप अधिसूचनाओं को अपने डिज़ाइन में अनचाहे उपयोगकर्ता इनपुट के रूप में वर्गीकृत करने का प्रयास करें। मुझे विश्वास है कि यह कुछ conundrums हल करने में मदद कर सकते हैं।

+0

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

+0

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

+0

मैं केवल जोड़ता हूं एक प्रस्तुतकर्ता अगर मेरा वीसी बहुत बड़ा हो रहा है। लेकिन एक UITableViewController की कल्पना करें, आप सरणी को डेटा के साथ कहां रखते हैं? –

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