कुछ उपयोगकर्ताओं के लिए सुविधाओं को छुपाना / अक्षम करना


11

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

क्या एक ध्वज के आधार पर एक उपलब्धता को टॉगल करने के लिए एक पैटर्न है जो स्टार्टअप पर लोड करता है (जैसे निःशुल्क / भुगतान)?

मुझे हर जगह निम्नलिखित कोड ब्लॉक होने का विचार पसंद नहीं है:

if(isFreeVersion){
    // ...
} else {
    // ...
}

प्रत्येक संस्करण के लिए 2 अलग-अलग गिट शाखाएं होना एक विकल्प नहीं है क्योंकि इसका मतलब होगा 2 (या अधिक) कोड स्रोतों को बनाए रखना, सामान्य रूप से अव्यवहारिक लगता है और यहां अधिक चर्चा की जाती है: संस्करण नियंत्रण में समान कोडबेस से दो अलग सॉफ्टवेयर संस्करण बनाए रखना

क्या ऐसा करने का एक तरीका है, जबकि अभी भी एक ही कोड आधार है और कोड को सशर्त बयानों से मुक्त नहीं करना है जो कि मुफ्त / भुगतान किए गए ध्वज की जांच करते हैं?

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

हम Android / Java का उपयोग करते हैं।



@gnat tnx, अच्छा लगता है। लेकिन मैं उन विकल्पों पर चर्चा करना चाहूंगा जिनके लिए अलग-अलग शाखाओं की आवश्यकता नहीं है और कई कोडबेस बनाए रखने की आवश्यकता है
तदिजा बगरिक

2
यह विभिन्न प्राधिकरण स्तरों के समान है। आप इस बात पर गौर कर सकते हैं कि आम तौर पर उस समस्या से कैसे निपटा जाता है, जहां एक सुविधा केवल कुछ उपयोगकर्ताओं / भूमिकाओं के लिए उपलब्ध है।
बार्ट वैन इनगेन शेनौ

@BartvanIngenSchenau मुझे लगता है कि ज्यादातर ifवर्जित सुविधाओं के नियंत्रण को छिपाने के लिए चेक किया जाता है या जब उपयोगकर्ता वह करने की अनुमति नहीं देता है जो करने की कोशिश करता है, तो पॉपअप संवाद के लिए। मैं कोड में कई शर्तों से बचने का एक तरीका खोजने की उम्मीद कर रहा हूं
तदिजा बगरिक

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

जवाबों:


9

यदि आपको if/elseब्लॉक पसंद नहीं हैं , तो आप उन्हें वंशानुक्रम का उपयोग करने के लिए रिफ्लेक्टर कर सकते हैं ( मारिन फाउलर की रिफैक्टिंग पुस्तक से बहुरूपता के साथ सशर्त बदलें देखें )। यह ऐसा होगा:

  • अपने कोड के बारे में तर्क करने के लिए इसे थोड़ा सरल बनाएं।

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

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


3
मुझे लगता है कि आप अधिक स्पष्ट होना चाह सकते हैं कि इसके लिए कार्यान्वयन की विरासत की आवश्यकता नहीं है। एक और लाभ यह है कि मुफ्त ऐप को प्रीमियम सुविधाओं के बिना दिया जा सकता है। जावा बाइट कोड को संशोधित करना अगर एक शर्त को हमेशा सही बनाता है तो बहुत मुश्किल नहीं है।
जिमीजैम

15

एक सशर्त जैसे कोड में if(isFreeVersion)सिर्फ एक बार होना चाहिए । यह एक पैटर्न नहीं है, लेकिन मुझे यकीन है कि आप पहले से ही इसके लिए नाम जानते हैं: इसे DRY सिद्धांत कहा जाता हैif(isFreeVersion)आपके कोड में एक से अधिक स्थानों पर " " जैसे कोड होने का मतलब है कि आपने इस पंक्ति / तर्क को दोहराया है, जिसका अर्थ है कि इसे पुनरावृत्ति से बचने के लिए फिर से भरना चाहिए।

" if(isFreeVersion)" का उपयोग विभिन्न विशेषताओं के लिए आंतरिक कॉन्फ़िगरेशन विकल्पों की सूची स्थापित करने के लिए किया जाना चाहिए। परिणामी कोड तब इस तरह दिख सकता है:

 if(isFreeVersion)
 {
      feature1Enabled=false;
      feature2Enabled=false;
      maxNoOfItems=5;
      advertisingStrategy=new ShowLotsOfAdvertisementsStrategy();
      // ...
 } 
 else
 {
      feature1Enabled=true;
      feature2Enabled=true;
      maxNoOfItems=int.MaxValue; // virtually unlimited
      advertisingStrategy=new ShowMinimalAdvertisementsStrategy();
 }

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

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

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

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

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


5
आपने मूल रूप से IsFreeVersion को FeaturexEnabled से बदल दिया है, आपने कॉल की संख्या कम नहीं की है। हालांकि मुझे ऐसा बिल्कुल नहीं लगा है कि मैंने हमेशा मेन्यू क्रिएशन द्वारा इसी तरह के सामान को संभाला है जो उन विकल्पों को अक्षम करता है जो उपयोगकर्ता को नहीं देखना चाहिए। अधिकतर यह फॉर्म निर्माण पर होता है लेकिन पॉप-अप मेनू तैयार करते समय मुझे कभी-कभी ऐसा करना पड़ता है।
लोरेन Pechtel

1
@ लोरेनपेकटेल: आपको मेरा जवाब फिर से पढ़ना चाहिए, अधिक ध्यान से। मैंने वास्तव में सशर्त परीक्षणों की संख्या को कम करने के लिए दो चीजों का उल्लेख किया था , उनमें से एक DRY सिद्धांत, उनमें से एक UI में परीक्षणों पर ध्यान केंद्रित करना था। अधिक महत्वपूर्ण है, की तरह एक unspecific झंडा मानचित्रण isFreeVersionके लिए विशिष्ट सुविधा मापदंडों हटा देगा उन परीक्षणों के दर्द से ज्यादातर - वे वास्तव में समझ बनाने के लिए शुरू कर देंगे और एक रखरखाव गंदगी किसी भी अधिक उत्पादन नहीं करते।
डॉक ब्राउन

6

मुझे लगता है कि आपके प्रश्न को फ़ीचर टॉगल पैटर्न को लागू करने से बहुत अच्छी तरह से हल किया जा सकता है ।

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

कुछ पुस्तकालय भी हैं जो इस पैटर्न का समर्थन करते हैं। मुझे जावा में FF4J के साथ काम करने का अनुभव था लेकिन अगर आप टाइप करते हैं तो मुझे लगता है:

feature toggle <whatever language you prefer>

... किसी भी खोज इंजन में आपको कई समाधान मिलेंगे।


2

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

जब आप सर्वलेट्स, जेम्स मेल्स और यहां तक ​​कि आईडीई प्लगइन्स को देखते हैं, तो वे सभी प्लग-इन आर्किटेक्चर की अवधारणा का उपयोग करते हैं:

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

क्या यह भी आप विभिन्न दर्शकों के लिए उपलब्ध सुविधाओं के विभिन्न वर्गों के लिए अवसर है अनुमति देता है। उपयोगकर्ताओं के पास केवल वे सुविधाएँ हैं जिनके लिए उन्होंने भुगतान किया है।

आपके एप्लिकेशन कोड को एक कोड बेस के रूप में बनाए रखा जाता है, और आपका प्लग-इन एक अलग कोड बेस होता है - लेकिन इसमें वे भाग शामिल होते हैं जो प्लगइन के लिए प्रासंगिक होते हैं। एप्लिकेशन को मौजूद होने पर प्लगइन्स से निपटना जानता है, और प्लगइन केवल इंटरफ़ेस के साथ बातचीत करना जानता है।

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