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




design-patterns architecture (4)

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

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

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

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

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

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

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


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

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

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

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


आर्टम के जवाब में बड़ी सलाहयों की तुलना में एक मामूली मुद्दा, लेकिन कोड पठनीयता के संदर्भ में, मुझे एपीआई को पूरी तरह से 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 वस्तु "बहुत भीड़" लग रही है, तो यह एक संकेत है कि सेवा बहुत अधिक कर रही है।


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

नियंत्रक

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

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

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

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

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

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

क्षेत्र

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

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

आदर्श

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

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

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

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

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

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

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

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

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

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

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

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

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 में किसी भी तरीके को परिभाषित न करें। यह अप्रत्याशित व्यवहार का कारण बन सकता है जब आपके व्यू स्कोप के भीतर ngModel निर्देश के साथ प्रयोग किया जाता है, आमतौर पर आपके दायरे को कूड़ा कर देता है और मुद्दों को ओवरराइड करने के दायरे के तरीकों की ओर जाता है।

संसाधन

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

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

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

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

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

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

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

सेवाएं

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

सेवाएं असंबद्ध हैं, कार्यक्षमता की कमजोर युग्मित इकाइयां जो स्वयं निहित हैं।

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

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

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

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

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

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

ग्राहक-पक्ष संरचना

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

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

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

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

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

विवरण के लिए कृपया बड़े अंगुलरजेएस और जावास्क्रिप्ट अनुप्रयोगों में कोड संगठन देखें।

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

|-- 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


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

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

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

दिशानिर्देश

दृश्य

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

कर:

  • वर्तमान स्कोप चर (केवल पढ़ने के लिए)।
  • कार्यों के लिए नियंत्रक को बुलाओ।

मत करो:

  • कोई तर्क दें

मोहक, संक्षिप्त, और हानिरहित यह दिखता है:

ng-click="collapsed = !collapsed"

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

नियंत्रकों

कर:

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

मत करो:

  • किसी भी व्यावसायिक तर्क के साथ सौदा करें।

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

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

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

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

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

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

एक मॉडल क्या है?

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

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

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

असली मॉडल जारी रखना चाहिए

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

परिणाम

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

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

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

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

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

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

प्रश्न अभी भी बनी हुई है - आप उन्हें एक कोणीय अनुप्रयोग के भीतर कहां फेंकते हैं?

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

ये सभी एमवीडब्ल्यू ढांचे 3 परतों का उपयोग करते हैं:

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

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

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

यहां वास्तविक सौदा आवेदन व्यवसाय नियम परत (मामलों का उपयोग करें) है, जो अक्सर ग्राहकों पर अस्वस्थ हो जाता है।

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

कंक्रीट उदाहरण

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

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

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

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

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

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

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

निम्नलिखित चित्र दिखाता है कि कैसे कोणीय ग्राहकों में एक और अनुप्रयोग तर्क परत जोड़कर ऊपर की समस्या हल हो सकती है:

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

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

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

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




client-side