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

निर्णय
विकसित अनुप्रयोग में,
निर्भरता इंजेक्शन पैटर्न का उपयोग किया जाता है, इसलिए कुछ घटकों के साथ आवेदन घटकों को सेवाओं के रूप में प्रस्तुत किया जाता है। निम्नलिखित समस्या के समाधान में भाग लेंगे:
- कुकीज़ रिपोजिटरी
- HTTP रिक्वेस्ट डेटा रिपॉजिटरी (GET पैरामीटर, document.location.pathname, आदि);
- और, सीधे, टैग प्राप्त करने की सेवा।
हम उन्हें क्रमशः
कुकीज़ ,
क्वेरी और
यूटीएम कहते हैं।
यदि कुकीज़ और क्वेरी की कार्यक्षमता पर्याप्त रूप से स्पष्ट है, तो utm के बारे में क्या? क्या यूटीएम या अमूर्त के अंदर सीधे लेबल प्राप्त करने के लिए एल्गोरिथ्म को लागू करना और सेवा के बाहर एल्गोरिथ्म का कार्यान्वयन करना इसके लायक है?
एल्गोरिथ्म को बहुत सरल बनाया जा सकता है यदि:
- एक एकल इंटरफ़ेस के साथ एक सार डेटा स्रोत की अवधारणा का परिचय;
- टैग्स को आवश्यक और वैकल्पिक में अलग करें।

तदनुसार, स्रोत हमारी कुकीज़ और क्वेरी सेवाएं होनी चाहिए।
लेकिन क्या होगा अगर कुकी पाने वाले के पास कुकी मान getCookie है, और क्वेरी गेट्टर पैरामीटर getQueryParameter है?
दूसरे शब्दों में, हमें
एडेप्टर पैटर्न का उपयोग करने की आवश्यकता है।
परिणामस्वरूप, निम्न आवरण सेवाएँ दिखाई देंगी:
- कुकीज़-यूटीएम-एडेप्टर - एक खोज करता है और, यदि आवश्यक हो, कुकीज़ में एक संग्रहीत लेबल को डीकोड करता है;
- क्वेरी-यूटीएम-एडाप्टर - जीईटी मापदंडों में एक खोज करता है;
- क्वेरी-यूटीएम-एडेप्टर-बैकसाइड - एक HTTP अनुरोध के अप्रत्यक्ष विशेषताओं के आधार पर एक खोज करता है।
Utm सेवा में एक addSource विधि होगी जो किसी ऑब्जेक्ट में लेबल स्रोत इंटरफ़ेस और इस स्रोत के लिए प्राथमिकता के साथ लेता है। इसके अलावा, सेवा डिजाइनर एक जावास्क्रिप्ट ऑब्जेक्ट को स्वीकार करता है जो सेवा की डिफ़ॉल्ट सेटिंग्स का विस्तार करता है।
यह चित्र कुकीज़ रिपॉजिटरी के साथ utm सेवा के कनेक्शन को दिखाता है:

सेवाओं में यह सब इस तरह दिखाई देगा:
cookies: path: '/src/service/cookies/cookies.js' query: path: '/src/service/query/query.js' cookies-utm-adapter: path: '/src/service/utm/cookies-utm-adapter.js' deps: calls: [['setCookieService', ['@cookies']] query-utm-adapter: path: '/src/service/utm/query-utm-adapter.js' deps: calls: [['setQueryService', ['@query']] query-utm-adapter-backside: path: 'src/service/utm/query-utm-adapter-backside.js' deps: calls: [['setQueryService', ['@query']] utm: path: 'src/service/utm/utm.js' deps: args: [ parameters: [ name: 'utm_source' required: true , name: 'utm_content' required: false , name: 'utm_term' required: false ] ] calls: [ ['addSource', ['@cookies-utm-adapter', 0]], ['addSource', ['@query-utm-adapter', 1]], ['addSource', ['@query-utm-adapter-backside', 2]] ]
* इस उदाहरण में, विन्यास को कॉफ़ीस्क्रिप्ट में प्रस्तुत किया गया है, @ अक्षर का मतलब सेवा उदाहरण के लिए लिंक है। एक समान कॉन्फ़िगरेशन प्रारूप का उपयोग सिम्फनी डिपेंडेंसी इंजेक्शन घटक में किया जाता है।कल्पना कीजिए कि हमने इस पूरी चीज़ को लागू और कोड किया है। अब सब कुछ काम करता है, लेकिन यह तुल्यकालिक रूप से काम करता है। कुछ चिह्नों की "उम्मीद" के साथ क्या करना है?
Async.js + jQuery.Deferred
कार्यान्वयन के बारे में कुछ शब्द।
चयनित संरचनात्मक समाधान के दो तार्किक स्तर हैं:
- यूटीएम सेवा के अंदर मतदान स्रोतों का तर्क;
- एडॉप्टर लॉजिक, जो बहुत भिन्न हो सकता है - एक साधारण कॉल से एक एम्बेडेड रिपॉजिटरी तक, लेबल डेटा प्राप्त करने और प्रारूपित करने के लिए सबसे अधिक परिष्कृत तरीके।
एक अतुल्यकालिक समाधान को लागू करने के लिए, हमें कम से कम पहले स्तर पर परिवर्तन करने की आवश्यकता है।
Utm सेवा स्तर पर, हम स्रोत सर्वेक्षण चक्र के कार्यान्वयन को बदल देंगे:
- हम async.js लाइब्रेरी का उपयोग करके लूप को अतुल्यकालिक बना देंगे जो अतुल्यकालिक शैली में संग्रह के लिए बुनियादी तरीकों को लागू करता है;
- प्राप्त विधि के लिए एक कॉल के जवाब में, एडेप्टर या तो लेबल मूल्य या इसके मूल्य (वादा) के लिए एक वादा की उम्मीद करेगा - उस स्थिति में जब एडाप्टर को इसके लिए प्रतीक्षा करने या कहीं अनुरोध करने की आवश्यकता होती है। परिणाम को संसाधित करना $ .when विधि में लिपटा है और यदि सफलतापूर्वक हल हो गया है, तो async कॉलबैक लूप फ़ंक्शन को कॉल करता है।
एडेप्टर स्तर पर, हम उन लेबलों के लिए एक वादा रिटर्न जोड़ेंगे जो प्रतीक्षा के लायक हैं। उदाहरण के लिए, __utmz कुकी, जो ga.js लाइब्रेरी के आरंभ होने के बाद सेट की गई है (analytics.js) और कुछ टैग को परिभाषित करने की अनुमति दे सकती है।
निष्कर्ष
कभी-कभी, समस्या के डिजाइन की शुरुआत में, हम हमेशा इसकी जटिलता और सभी नुकसानों की कल्पना नहीं करते हैं। और ऐसे क्षणों में, मैं इसे जितना संभव हो उतना सरल बनाना चाहता हूं, लेकिन कोड के अत्यधिक विखंडन से अधिक इंजीनियरिंग के विचारों का पता चलता है और सामान्य तौर पर थोड़ा डरावना है। इस मामले में, डिजाइन की "शुद्धता" ने फल पैदा किया है और आवेदन तर्क में और संशोधनों को बहुत सरल बना दिया है।
आपका ध्यान के लिए धन्यवाद! आशा है कि यह किसी की मदद करता है।