AngularJS: डिजाइन पैटर्न को समझना


147

इगोर मिनार की इस पोस्ट के संदर्भ में , कोणीयजेएस का नेतृत्व:

एमवीसी बनाम एमवीवीएम बनाम एमवीपी । क्या एक विवादास्पद विषय है जिसके बारे में बहस करने और बहस करने के लिए कई डेवलपर्स घंटों और घंटे बिता सकते हैं।

कई वर्षों के लिए AngularJS MVC (या इसके क्लाइंट-साइड वेरिएंट में से एक) के करीब था, लेकिन समय के साथ और कई रिफ्लेक्टरिंग और एपीआई सुधारों के लिए धन्यवाद, अब यह MVVM के करीब है - $ गुंजाइश ऑब्जेक्ट को ViewModel माना जा सकता है एक फ़ंक्शन द्वारा सजाया गया जिसे हम एक नियंत्रक कहते हैं ।

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

कहा जाने के बाद, मैं देख रहा हूँ कि डेवलपर्स किक-एश ऐप्स का निर्माण करते हैं जो अच्छी तरह से डिज़ाइन किए गए हैं और चिंताओं को अलग करने का पालन करते हैं, उन्हें देखने से बर्बाद समय एमवी * बकवास के बारे में बहस करते हैं। और इस कारण से, मैं एंगुलरजेएस को एमवीडब्ल्यू फ्रेमवर्क - मॉडल-व्यू-जो भी घोषित करता हूं । जहाँ भी जो कुछ भी " आपके लिए काम करता है " के लिए खड़ा है ।

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

क्या क्लाइंट-साइड एप्लिकेशन में AngularJS MVW (मॉडल-व्यू-जो भी) डिजाइन पैटर्न को लागू करने के लिए कोई सिफारिशें या दिशानिर्देश हैं?


के लिए upvoted ... से उन्हें देखने के लिए बर्बाद समय MV * बकवास के बारे में बहस।
शिरगिल फरहान

1
एक शब्द वर्ग डिजाइन पैटर्न का पालन करने के लिए आपको कोणीय की आवश्यकता नहीं है।
उपयोगी

जवाबों:


223

AngularJS ऐप्स में घटकों को लागू करने के लिए कुछ सामान्य सिफारिशें प्राप्त करने के लिए बहुत बड़ी मात्रा में मूल्यवान स्रोतों के लिए धन्यवाद:


नियंत्रक

  • नियंत्रक केवल मॉडल और दृश्य के बीच एक इंटरलेयर होना चाहिए । इसे जितना संभव हो उतना पतला बनाने की कोशिश करें ।

  • नियंत्रक में व्यावसायिक तर्क से बचने के लिए यह अत्यधिक अनुशंसित है । इसे मॉडल में स्थानांतरित किया जाना चाहिए।

  • नियंत्रक विधि आह्वान का उपयोग करके अन्य नियंत्रकों के साथ संवाद कर सकता है (संभव है जब बच्चे माता-पिता के साथ संवाद करना चाहते हैं) या $ emit , $ प्रसारण और विधियों पर $ । उत्सर्जित और प्रसारित संदेशों को न्यूनतम रखा जाना चाहिए।

  • नियंत्रक को प्रस्तुति या DOM हेरफेर के बारे में परवाह नहीं करनी चाहिए ।

  • नेस्टेड नियंत्रकों से बचने की कोशिश करें । इस मामले में माता-पिता नियंत्रक को मॉडल के रूप में व्याख्या की जाती है। इसके बजाय साझा सेवाओं के रूप में मॉडल इंजेक्ट करें।

  • स्कोप नियंत्रक में के लिए इस्तेमाल किया जाना चाहिए बंधन दृश्य के साथ मॉडल और
    encapsulating देखें मॉडल के लिए के रूप में प्रस्तुति मॉडल डिजाइन पैटर्न।


क्षेत्र

टेम्प्लेट को केवल टेम्प्लेट के रूप में पढ़ें और केवल नियंत्रकों में लिखें । स्कोप का उद्देश्य मॉडल को संदर्भित करना है, न कि मॉडल होना।

जब द्विदिश बाइंडिंग (एनजी-मॉडल) कर रहे हों, तो सुनिश्चित करें कि आप सीधे स्कोप गुणों से बंधे नहीं हैं।


नमूना

एंगुलरजेएस में मॉडल सेवा द्वारा परिभाषित एक सिंगलटन है ।

मॉडल डेटा और प्रदर्शन को अलग करने का एक शानदार तरीका प्रदान करता है।

मॉडल यूनिट परीक्षण के लिए प्रमुख उम्मीदवार हैं, क्योंकि उनके पास आम तौर पर एक ही निर्भरता होती है (घटना के कुछ रूप होते हैं, सामान्य स्थिति में $ rootScope ) और अत्यधिक परीक्षण योग्य डोमेन तर्क होते हैं

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

  • मॉडल को आपके एप्लिकेशन के डेटा को एन्क्रिप्ट करना चाहिए और उस डेटा तक पहुंचने और हेरफेर करने के लिए एक एपीआई प्रदान करना चाहिए ।

  • मॉडल पोर्टेबल होना चाहिए ताकि इसे आसानी से इसी तरह के एप्लिकेशन में पहुंचाया जा सके।

  • अपने मॉडल में यूनिट लॉजिक को अलग करके आपने इसे ढूंढना, अपडेट करना और बनाए रखना आसान बना दिया है।

  • मॉडल अधिक सामान्य वैश्विक मॉडल के तरीकों का उपयोग कर सकता है जो पूरे अनुप्रयोग के लिए सामान्य हैं।

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

  • मॉडल में इवेंट श्रोताओं का उपयोग करने से बचने की कोशिश करें। यह उन्हें परीक्षण करने के लिए कठिन बनाता है और आम तौर पर एकल-जिम्मेदारी-सिद्धांत के संदर्भ में मॉडल को मारता है।

मॉडल कार्यान्वयन

जैसा कि मॉडल को डेटा और स्थिति के संदर्भ में कुछ तर्क देना चाहिए, इसे अपने सदस्यों तक पहुंच को सीमित करना चाहिए ताकि हम ढीले युग्मन की गारंटी दे सकें।

AngularJS एप्लिकेशन में इसे करने का तरीका कारखाना सेवा प्रकार का उपयोग करके इसे परिभाषित करना है । इससे हम निजी संपत्तियों और विधियों को बहुत आसानी से परिभाषित कर सकते हैं और एक ही स्थान पर सार्वजनिक रूप से सुलभ लोगों को भी लौटा सकते हैं जो इसे डेवलपर के लिए वास्तव में पठनीय बना देगा।

एक उदाहरण :

angular.module('search')
.factory( 'searchModel', ['searchResource', function (searchResource) {

  var itemsPerPage = 10,
  currentPage = 1,
  totalPages = 0,
  allLoaded = false,
  searchQuery;

  function init(params) {
    itemsPerPage = params.itemsPerPage || itemsPerPage;
    searchQuery = params.substring || searchQuery;
  }

  function findItems(page, queryParams) {
    searchQuery = queryParams.substring || searchQuery;

    return searchResource.fetch(searchQuery, page, itemsPerPage).then( function (results) {
      totalPages = results.totalPages;
      currentPage = results.currentPage;
      allLoaded = totalPages <= currentPage;

      return results.list
    });
  }

  function findNext() {
    return findItems(currentPage + 1);
  }

  function isAllLoaded() {
    return allLoaded;
  }

  // return public model API  
  return {
    /**
     * @param {Object} params
     */
    init: init,

    /**
     * @param {Number} page
     * @param {Object} queryParams
     * @return {Object} promise
     */
    find: findItems,

    /**
     * @return {Boolean}
     */
    allLoaded: isAllLoaded,

    /**
     * @return {Object} promise
     */
    findNext: findNext
  };
});

नए उदाहरण पैदा करना

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

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

angular.module('car')
 .factory( 'carModel', ['carResource', function (carResource) {

  function Car(data) {
    angular.extend(this, data);
  }

  Car.prototype = {
    save: function () {
      // TODO: strip irrelevant fields
      var carData = //...
      return carResource.save(carData);
    }
  };

  function getCarById ( id ) {
    return carResource.getById(id).then(function (data) {
      return new Car(data);
    });
  }

  // the public API
  return {
    // ...
    findById: getCarById
    // ...
  };
});

ग्लोबल मॉडल

सामान्य तौर पर ऐसी स्थितियों से बचने और अपने मॉडल को ठीक से डिजाइन करने की कोशिश करें ताकि इसे कंट्रोलर में इंजेक्ट किया जा सके और आपके विचार में इसका उपयोग किया जा सके।

विशेष रूप से कुछ मामलों में आवेदन के भीतर वैश्विक पहुंच की आवश्यकता होती है। इसे संभव बनाने के लिए आप $ rootScope में ' कॉमन ' प्रॉपर्टी को परिभाषित कर सकते हैं और एप्लीकेशन बूटस्ट्रैप के दौरान इसे कॉमनमॉडल से बाँध सकते हैं :

angular.module('app', ['app.common'])
.config(...)
.run(['$rootScope', 'commonModel', function ($rootScope, commonModel) {
  $rootScope.common = 'commonModel';
}]);

आपकी सभी वैश्विक विधियां ' सामान्य ' संपत्ति के भीतर रहेंगी । यह किसी प्रकार का नामस्थान है

लेकिन किसी भी तरीके को सीधे अपने $ rootScope में परिभाषित न करें । यह अनपेक्षित व्यवहार के कारण हो सकता है जब आपके दृश्य क्षेत्र के भीतर एनकॉडेल निर्देश के साथ उपयोग किया जाता है, आम तौर पर आपके दायरे को कम करके और समस्याओं को ओवरराइड करने के लिए गुंजाइश वाले तरीकों की ओर जाता है।


संसाधन

संसाधन आपको विभिन्न डेटा स्रोतों के साथ सहभागिता करने देता है

एकल-जिम्मेदारी-सिद्धांत का उपयोग करके लागू किया जाना चाहिए ।

विशेष रूप से यह HTTP / JSON के समापन बिंदु के लिए पुन: प्रयोज्य प्रॉक्सी है।

संसाधन मॉडल में इंजेक्ट किए जाते हैं और डेटा भेजने / पुनः प्राप्त करने की संभावना प्रदान करते हैं।

संसाधन कार्यान्वयन

एक कारखाना जो एक संसाधन ऑब्जेक्ट बनाता है जो आपको RESTful सर्वर-साइड डेटा स्रोतों के साथ सहभागिता करने देता है।

लौटे संसाधन ऑब्जेक्ट में एक्शन विधियाँ हैं जो निम्न स्तर $ http सेवा के साथ सहभागिता की आवश्यकता के बिना उच्च-स्तरीय व्यवहार प्रदान करती हैं।


सेवाएं

मॉडल और संसाधन दोनों ही सेवाएं हैं

सेवाएँ अनसोर्स्ड हैं, कार्यक्षमता की शिथिल युग्मित इकाइयाँ जो स्व-निहित हैं।

सेवाएँ एक सुविधा है जो कोणीय सर्वर साइड से क्लाइंट-साइड वेब ऐप्स पर लाती है, जहां सेवाओं का आमतौर पर लंबे समय से उपयोग किया जाता है।

एंगुलर एप्स में सेवाएं एक स्थानापन्न वस्तु हैं जो निर्भरता इंजेक्शन का उपयोग करके एक साथ वायर्ड की जाती हैं।

कोणीय विभिन्न प्रकार की सेवाओं के साथ आता है। प्रत्येक अपने स्वयं के उपयोग के मामलों के साथ। कृपया विवरण के लिए अंडरस्टैंडिंग सेवा प्रकार पढ़ें ।

अपने आवेदन में सेवा वास्तुकला के मुख्य सिद्धांतों पर विचार करने का प्रयास करें ।

सामान्य रूप से वेब सेवा शब्दावली के अनुसार :

एक सेवा एक अमूर्त संसाधन है जो कार्य करने की क्षमता का प्रतिनिधित्व करता है जो प्रदाताओं संस्थाओं और अनुरोध संस्थाओं के दृष्टिकोण से एक सुसंगत कार्यक्षमता बनाता है। उपयोग किए जाने के लिए, एक सेवा को एक ठोस प्रदाता एजेंट द्वारा महसूस किया जाना चाहिए।


क्लाइंट-साइड संरचना

आवेदन के सामान्य ग्राहक पक्ष में मॉड्यूल में विभाजित किया गया है । प्रत्येक मॉड्यूल को एक इकाई के रूप में परीक्षण योग्य होना चाहिए ।

प्रकार से नहीं, सुविधा / कार्यक्षमता या दृश्य के आधार पर मॉड्यूल को परिभाषित करने का प्रयास करें । देखें Misko की प्रस्तुति जानकारी के लिए।

मॉड्यूल घटकों को पारंपरिक रूप से नियंत्रक, मॉडल, विचार, फ़िल्टर, निर्देश आदि जैसे प्रकारों द्वारा वर्गीकृत किया जा सकता है।

लेकिन मॉड्यूल ही पुन: प्रयोज्य , हस्तांतरणीय और परीक्षण योग्य रहता है ।

डेवलपर्स के लिए कोड के कुछ हिस्सों और इसकी सभी निर्भरताओं को खोजना बहुत आसान है।

कृपया विवरण के लिए कोड ऑर्गनाइजेशन इन लार्ज एंगुलरजेएस और जावास्क्रिप्ट एप्लिकेशन देखें।

फ़ोल्डरों की संरचना का एक उदाहरण :

|-- src/
|   |-- app/
|   |   |-- app.js
|   |   |-- home/
|   |   |   |-- home.js
|   |   |   |-- homeCtrl.js
|   |   |   |-- home.spec.js
|   |   |   |-- home.tpl.html
|   |   |   |-- home.less
|   |   |-- user/
|   |   |   |-- user.js
|   |   |   |-- userCtrl.js
|   |   |   |-- userModel.js
|   |   |   |-- userResource.js
|   |   |   |-- user.spec.js
|   |   |   |-- user.tpl.html
|   |   |   |-- user.less
|   |   |   |-- create/
|   |   |   |   |-- create.js
|   |   |   |   |-- createCtrl.js
|   |   |   |   |-- create.tpl.html
|   |-- common/
|   |   |-- authentication/
|   |   |   |-- authentication.js
|   |   |   |-- authenticationModel.js
|   |   |   |-- authenticationService.js
|   |-- assets/
|   |   |-- images/
|   |   |   |-- logo.png
|   |   |   |-- user/
|   |   |   |   |-- user-icon.png
|   |   |   |   |-- user-default-avatar.png
|   |-- index.html

कोणीय एप्लिकेशन संरचना का अच्छा उदाहरण कोणीय-ऐप द्वारा कार्यान्वित किया जाता है - https://github.com/angular-app/angular-app/tree/master/client/src

यह आधुनिक एप्लिकेशन जनरेटर द्वारा भी माना जाता है - https://github.com/yeoman/generator-angular/issues/109


5
मुझे इस बारे में एक चिंता है: "नियंत्रक में व्यावसायिक तर्क से बचने के लिए यह अत्यधिक अनुशंसित है। इसे मॉडल में स्थानांतरित किया जाना चाहिए।" हालाँकि आधिकारिक दस्तावेज़ से आप पढ़ सकते हैं: "सामान्य तौर पर, एक नियंत्रक को बहुत अधिक करने की कोशिश नहीं करनी चाहिए। इसमें केवल एक दृश्य के लिए आवश्यक व्यावसायिक तर्क होना चाहिए।" क्या हम एक ही चीज के बारे में बात कर रहे हैं?
op1ekun

3
मैं कहूंगा - नियंत्रक को मॉडल के रूप में देखें।
आर्टेम प्लैटोनोव

1
+1। यहाँ कुछ बेहतरीन सलाह! 2. दुर्भाग्य से searchModelफिर से प्रयोज्य सलाह का उदाहरण नहीं है। बेहतर होगा कि constantसेवा के माध्यम से स्थिरांक आयात करें । 3. किसी भी व्याख्या का यहाँ क्या मतलब है ?:Try to avoid having a factory that returns a new able function
दिमित्री ज़ैतसेव

1
इसके अलावा ऑब्जेक्ट की prototypeसंपत्ति को अधिलेखित करने से वंशानुक्रम टूट जाता है, इसके बजाय एक का उपयोग कर सकते हैंCar.prototype.save = ...
दिमित्री जैतसेव

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

46

मेरा मानना ​​है कि इगोर का इस पर ध्यान देना, जैसा कि आपके द्वारा प्रदान किए गए उद्धरण में देखा गया है, यह एक बड़ी समस्या का हिमशैल टिप है।

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

चलो यह थोड़ा करके करते हैं।

दिशा निर्देश

दृश्य

कोणीय संदर्भ में, दृश्य DOM है। दिशानिर्देश हैं:

करना:

  • वर्तमान गुंजाइश चर (केवल पढ़ें)।
  • क्रियाओं के लिए नियंत्रक को कॉल करें।

मत करो:

  • कोई भी तर्क रखो।

लुभावना, छोटा और हानिरहित होने के कारण यह दिखता है:

ng-click="collapsed = !collapsed"

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

नियंत्रकों

करना:

  • डेटा को दायरे पर रखकर 'मॉडल' पर विचार करें।
  • उपयोगकर्ता क्रियाओं का जवाब दें।
  • प्रस्तुति तर्क से निपटें।

मत करो:

  • किसी भी व्यावसायिक तर्क से निपटें।

अंतिम दिशानिर्देश का कारण यह है कि नियंत्रक बहनों के विचार हैं, संस्थाओं के नहीं; न ही वे पुन: प्रयोज्य हैं।

आप यह तर्क दे सकते हैं कि निर्देश पुन: प्रयोज्य हैं, लेकिन निर्देश भी विचारों (डीओएम) के लिए बहनें हैं - वे कभी भी संस्थाओं के अनुरूप नहीं थे।

ज़रूर, कभी-कभी विचार संस्थाओं का प्रतिनिधित्व करते हैं, लेकिन यह एक विशिष्ट मामला है।

दूसरे शब्दों में, नियंत्रक प्रस्तुति पर ध्यान केंद्रित करेंगे - यदि आप व्यापार तर्क को फेंकते हैं, तो न केवल आप एक फुलाया हुआ, थोड़ा प्रबंधनीय नियंत्रक के साथ समाप्त होने की संभावना रखते हैं, बल्कि आप चिंता सिद्धांत के अलगाव का भी उल्लंघन करते हैं ।

जैसे, कोणीय में नियंत्रक वास्तव में प्रस्तुति मॉडल या एमवीवीएम से अधिक हैं

और इसलिए, यदि नियंत्रकों को व्यावसायिक तर्क से निपटना नहीं चाहिए, तो किसे करना चाहिए?

मॉडल क्या है?

आपका क्लाइंट मॉडल अक्सर आंशिक और बासी होता है

जब तक आप एक ऑफ़लाइन वेब एप्लिकेशन या एक एप्लिकेशन नहीं लिख रहे हैं जो बहुत सरल है (कुछ निकाय), तो आप क्लाइंट मॉडल के लिए अत्यधिक महत्वपूर्ण हैं:

  • आंशिक
    • या तो इसमें सभी इकाइयाँ नहीं हैं (जैसे पृष्ठांकन के मामले में)
    • या इसमें सारा डेटा नहीं है (जैसे कि पेजेंटेशन के मामले में)
  • बासी - यदि सिस्टम में एक से अधिक उपयोगकर्ता हैं, तो किसी भी बिंदु पर आप यह सुनिश्चित नहीं कर सकते हैं कि क्लाइंट जिस मॉडल को रखता है वह सर्वर होल्ड के समान है।

असली मॉडल कायम रहना चाहिए

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

परिणाम

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

इस प्रकार, यह ग्राहक के संदर्भ में शायद समझदारी है, लोअरकेस का उपयोग करने के लिए M- इसलिए यह वास्तव में mVC , mVP और mVVm है । बड़ा Mसर्वर के लिए है।

व्यापार का तर्क

शायद व्यवसाय मॉडल के बारे में सबसे महत्वपूर्ण अवधारणाओं में से एक यह है कि आप उन्हें 2 प्रकारों में विभाजित कर सकते हैं (मैं तीसरे दृश्य-व्यापार को छोड़ देता हूं क्योंकि यह एक और दिन के लिए एक कहानी है):

  • डोमेन लॉजिक - उर्फ एंटरप्राइज बिजनेस रूल्स , लॉजिक जो एप्लिकेशन-इंडिपेंडेंट है। उदाहरण के लिए, एक मॉडल दें firstNameऔर sirNameगुणों के साथ , एक गेट्टर जैसे getFullName()एप्लिकेशन को स्वतंत्र माना जा सकता है।
  • एप्लीकेशन लॉजिक - उर्फ एप्लीकेशन बिजनेस रूल्स , जो एप्लीकेशन स्पेसिफिक है। उदाहरण के लिए, त्रुटि जांच और हैंडलिंग।

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

सवाल अभी भी बना हुआ है - आप उन्हें कोणीय अनुप्रयोग के भीतर कहाँ फेंकते हैं?

3 बनाम 4 परत वास्तुकला

ये सभी MVW फ्रेमवर्क 3 परतों का उपयोग करते हैं:

तीन वृत्त।  भीतरी - मॉडल, मध्य - नियंत्रक, बाहरी - दृश्य

लेकिन जब ग्राहकों की बात आती है तो इसके साथ दो मूलभूत मुद्दे होते हैं:

  • मॉडल आंशिक है, बासी है और कायम नहीं है।
  • एप्लिकेशन लॉजिक लगाने के लिए कोई जगह नहीं है।

इस रणनीति का एक विकल्प 4 परत की रणनीति है :

4 मंडलियां, आंतरिक से बाहरी तक - एंटरप्राइज़ व्यावसायिक नियम, अनुप्रयोग व्यवसाय नियम, इंटरफ़ेस एडेप्टर, फ्रेमवर्क और ड्राइवर

यहां असली सौदा एप्लीकेशन बिजनेस रूल्स लेयर (यूसेज केस) का है, जो अक्सर क्लाइंट्स पर भारी पड़ जाता है।

इस परत को इंटरैक्टर्स (अंकल बॉब) द्वारा महसूस किया जाता है, जो कि मार्टिन फाउलर ऑपरेशन स्क्रिप्ट सर्विस लेयर को कहते हैं

ठोस उदाहरण

निम्नलिखित वेब एप्लिकेशन पर विचार करें:

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

अब कुछ चीजें होनी चाहिए:

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

हम यह सब कहाँ फेंकते हैं?

यदि आपकी वास्तुकला में एक नियंत्रक शामिल है जो कॉल करता है $resource, तो यह सब नियंत्रक के भीतर होगा। लेकिन बेहतर रणनीति है।

एक प्रस्तावित समाधान

निम्नलिखित आरेख से पता चलता है कि ऊपर की समस्या को कैसे कोणीय क्लाइंट में एक और एप्लिकेशन लॉजिक परत जोड़कर हल किया जा सकता है:

4 बॉक्स - डोम कंट्रोलर को इंगित करता है, जो एप्लिकेशन लॉजिक को इंगित करता है, जो $ संसाधन की ओर इशारा करता है

इसलिए हम नियंत्रक के बीच $ संसाधन में एक परत जोड़ते हैं, यह परत (इसे अंतःक्रियाकर्ता कहते हैं ):

  • एक सेवा है । उपयोगकर्ताओं के मामले में, इसे कॉल किया जा सकता है UserInteractor
  • यह मामलों का उपयोग करने के लिए इसी तरीके प्रदान करता है , जो अनुप्रयोग तर्क को घेरता है
  • यह सर्वर से किए गए अनुरोधों को नियंत्रित करता है। नि: शुल्क-रूप मापदंडों के साथ $ संसाधन को नियंत्रित करने वाले नियंत्रक के बजाय, यह परत यह सुनिश्चित करती है कि सर्वर से किए गए अनुरोध डेटा पर डोमेन लॉजिक कार्य कर सकते हैं।
  • यह डोमेन लॉजिक प्रोटोटाइप के साथ लौटी डेटा संरचना को सजाता है ।

और इसलिए, ऊपर दिए गए ठोस उदाहरण की आवश्यकताओं के साथ:

  • उपयोगकर्ता 'उपयोगकर्ता जोड़ें' पर क्लिक करता है।
  • नियंत्रक एक रिक्त उपयोगकर्ता मॉडल के लिए इंटरेक्टर को पूछता है, जैसे व्यापार तर्क पद्धति से सजाया गया है validate()
  • प्रस्तुत करने पर, नियंत्रक मॉडल validate()विधि को कॉल करता है ।
  • यदि विफल हुआ, तो नियंत्रक त्रुटि को संभालता है।
  • सफल होने पर, नियंत्रक इंटरएक्टर को कॉल करता है createUser()
  • सहभागिताकर्ता $ संसाधन को कॉल करता है
  • प्रतिक्रिया देने पर, सहभागिताकर्ता किसी भी त्रुटि को नियंत्रक को सौंपता है, जो उन्हें संभालती है।
  • सफल प्रतिक्रिया पर, इंटरेक्टर सुनिश्चित करता है कि यदि आवश्यक हो, तो उपयोगकर्ता सूची अपडेट करता है।

इसलिए AngularJS को MVW (जहाँ W जो कुछ भी है) के लिए परिभाषित किया गया है क्योंकि मैं एक कंट्रोलर (इसमें सभी व्यावसायिक तर्क के साथ) या एक व्यू मॉडल / प्रस्तुतकर्ता (बिना व्यावसायिक तर्क के लेकिन सिर्फ कुछ कोड देख सकता हूँ) को BL के साथ चुन सकता हूं। एक अलग सेवा? क्या मैं सही हू?
BAD_SEED 22

सबसे बढ़िया उत्तर। क्या आपके पास 4-लेयर्ड कोणीय ऐप के GitHub पर एक वास्तविक उदाहरण है?
आरपीलैंड

1
@Rallas, नहीं, मैं नहीं चाहता (काश मेरे पास इसके लिए समय होता)। हम वर्तमान में एक आर्किटेक्चर की कोशिश कर रहे हैं, जहां 'एप्लीकेशन लॉजिक' सिर्फ एक सीमा-अंतःक्रियात्मक है; इसके बीच में एक रिज़ॉल्वर और नियंत्रक और एक दृश्य मॉडल जिसमें कुछ दृश्य तर्क होते हैं। हम अभी भी प्रयोग कर रहे हैं, इसलिए पेशेवरों या विपक्षों का 100% नहीं। लेकिन एक बार मैंने एक ब्लॉग लिखने की उम्मीद की थी।
इज़्हाकी

1
@ हेरिंग मूल रूप से, हमने मॉडल - OOP निर्माण पेश किए जो डोमेन संस्थाओं का प्रतिनिधित्व करते हैं। यह ये मॉडल हैं जो संसाधनों के साथ संवाद करते हैं, नियंत्रक नहीं। वे डोमेन लॉजिक को एनकैप्सुलेट करते हैं। नियंत्रक कॉल मॉडल, जो बदले में कॉल संसाधनों।
इज़्हाकी

1
@ alex440 नहीं, हालांकि अभी दो महीने हुए हैं कि इस विषय पर एक गंभीर ब्लॉग पोस्ट मेरी उंगलियों की नोक पर है। क्रिसमस आ रहा है - संभवतः तब।
इजाकी 22

5

आर्टेम के उत्तर में महान सलाह की तुलना में एक मामूली मुद्दा है, लेकिन कोड पठनीयता के संदर्भ में, मैंने returnऑब्जेक्ट के अंदर पूरी तरह से एपीआई को परिभाषित करने के लिए सबसे अच्छा पाया , कोड को आगे और पीछे जाने के लिए कम करने के लिए व्हीटरर चर को परिभाषित किया गया है:

angular.module('myModule', [])
// or .constant instead of .value
.value('myConfig', {
  var1: value1,
  var2: value2
  ...
})
.factory('myFactory', function(myConfig) {
  ...preliminary work with myConfig...
  return {
    // comments
    myAPIproperty1: ...,
    ...
    myAPImethod1: function(arg1, ...) {
    ...
    }
  }
});

यदि returnऑब्जेक्ट "बहुत भीड़" लग रहा है, तो यह एक संकेत है कि सेवा बहुत अधिक कर रही है।


0

AngularJS doest एमवीसी को पारंपरिक तरीके से लागू नहीं करता है, बल्कि यह MVVM (मॉडल-व्यू-व्यूमॉडल) के कुछ करीब लागू होता है, ViewModel को बाइंडर के रूप में भी संदर्भित किया जा सकता है (कोणीय मामले में यह $ गुंजाइश हो सकती है)। मॉडल -> जैसा कि हम जानते हैं कि कोणीय में मॉडल बस पुरानी जेएस ऑब्जेक्ट्स या हमारे एप्लिकेशन में डेटा हो सकता है

व्यू -> एंगुलरजेएस में दृश्य वह HTML है जिसे निर्देश या निर्देश या बाइंडिंग को लागू करके कोणीयजेएस द्वारा संकलित और संकलित किया गया है, मुख्य बिंदु यहां कोणीय में है इनपुट न केवल सादा HTML स्ट्रिंग (इनर HTML) है, बल्कि DOM ब्राउज़र द्वारा बनाया गया है।

ViewModel -> ViewModel वास्तव में angularJS मामले में आपके दृश्य और मॉडल के बीच का बांध / पुल है, यह $ गुंजाइश है जिसे हम नियंत्रक का उपयोग करने वाले $ गुंजाइश को शुरू करने और बढ़ाने के लिए करते हैं।

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


-1

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

कुल मिलाकर यह समस्याओं को हल करने के लिए विभिन्न ज्ञात डिज़ाइन पैटर्न का उपयोग करता है।

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