কেন কেউ প্রকাশ / সাবস্ক্রাইব প্যাটার্ন ব্যবহার করবে (জেএস / জিকুয়েরিতে)?


103

সুতরাং, একজন সহকর্মী আমাকে প্রকাশ / সাবস্ক্রাইব প্যাটার্নের (জেএস / জিকুয়েরিতে) পরিচয় করিয়ে দিয়েছিলেন, তবে কেন কেউ 'নরমাল' জাভাস্ক্রিপ্ট / জিকুয়েরির উপর এই প্যাটার্নটি ব্যবহার করতে পারে তা বুঝতে আমার খুব কষ্ট হচ্ছে ।

উদাহরণস্বরূপ, পূর্বে আমার কাছে নিম্নলিখিত কোডগুলি ছিল ...

$container.on('click', '.remove_order', function(event) {
    event.preventDefault();
    var orders = $(this).parents('form:first').find('div.order');
    if (orders.length > 2) {
        orders.last().remove();
    }
});

এবং আমি পরিবর্তে এটি করার যোগ্যতা দেখতে পেলাম, উদাহরণস্বরূপ ...

removeOrder = function(orders) {
    if (orders.length > 2) {
        orders.last().remove();
    }
}

$container.on('click', '.remove_order', function(event) {
    event.preventDefault();
    removeOrder($(this).parents('form:first').find('div.order'));
});

কারণ এটি removeOrderবিভিন্ন ইভেন্ট ইত্যাদির জন্য কার্যকারিতা পুনরায় ব্যবহার করার দক্ষতার পরিচয় দেয় etc.

তবে আপনি কেন প্রকাশ / সাবস্ক্রাইব প্যাটার্ন বাস্তবায়ন করার সিদ্ধান্ত নেবেন এবং যদি এটি একই কাজ করে তবে নিম্নলিখিত দৈর্ঘ্যে যান? (এফওয়াইআই, আমি jQuery ক্ষুদ্র পাব / সাব ব্যবহার করেছি )

removeOrder = function(e, orders) {
    if (orders.length > 2) {
        orders.last().remove();
    }
}

$.subscribe('iquery/action/remove-order', removeOrder);

$container.on('click', '.remove_order', function(event) {
    event.preventDefault();
    $.publish('iquery/action/remove-order', $(this).parents('form:first').find('div.order'));
});

আমি নিশ্চিতভাবে প্যাটার্নটি সম্পর্কে পড়েছি, তবে কেন এটি কখনও প্রয়োজন হবে তা আমি ঠিক ভাবতে পারি না। আমি যে টিউটোরিয়ালগুলি দেখেছি সেগুলি ব্যাখ্যা করে যে কীভাবে এই প্যাটার্নটি কার্যকর করা যায় কেবলমাত্র আমার নিজের মতো বুনিয়াদি উদাহরণগুলিকেও কভার করে।

আমি কল্পনা করি যে পাব / সাবটির উপযোগিতা আরও জটিল অ্যাপ্লিকেশনটিতে নিজেকে স্পষ্ট করে তুলবে, তবে আমি এটির কল্পনাও করতে পারি না। আমি ভীত যে আমি পুরোপুরি বিন্দুটি মিস করছি; তবে আমি যদি সেখানে একটি পয়েন্টটি জানতে চাই!

আপনি কী সংক্ষিপ্তভাবে ব্যাখ্যা করতে পারেন কেন এবং কোন পরিস্থিতিতে এই ধরণটি সুবিধাজনক? উপরের আমার উদাহরণগুলির মতো কোড স্নিপেটের জন্য কি পাব / সাব প্যাটার্নটি ব্যবহার করা উপযুক্ত?

উত্তর:


222

এগুলি সমস্ত আলগা সংযোগ এবং একক দায়িত্ব সম্পর্কে, যা জাভা স্ক্রিপ্টে এমভি * (এমভিসি / এমভিপি / এমভিভিএম) নিদর্শনগুলির সাথে একসাথে চলে যা যা গত কয়েক বছরে খুব আধুনিক।

লুজ কাপলিং হ'ল অবজেক্ট-ওরিয়েন্টেড নীতি, যাতে সিস্টেমের প্রতিটি উপাদান তার দায়িত্ব জানে এবং অন্যান্য উপাদানগুলির বিষয়ে চিন্তা করে না (বা কমপক্ষে যতটা সম্ভব তাদের যত্ন নেওয়ার চেষ্টা করে না)। লুজ কাপলিং একটি ভাল জিনিস কারণ আপনি সহজেই বিভিন্ন মডিউলটি পুনরায় ব্যবহার করতে পারেন। আপনি অন্যান্য মডিউলগুলির ইন্টারফেসের সাথে মিলিত হন না। প্রকাশ / সাবস্ক্রাইব ব্যবহার করে আপনি কেবল প্রকাশ / সাবস্ক্রাইব ইন্টারফেসের সাথে মিলিত হন যা কোনও বড় বিষয় নয় - মাত্র দুটি পদ্ধতি। সুতরাং আপনি যদি কোনও ভিন্ন প্রকল্পের কোনও মডিউল পুনরায় ব্যবহার করার সিদ্ধান্ত নেন তবে আপনি কেবল এটি অনুলিপি করে আটকে দিতে পারেন এবং এটি সম্ভবত কাজ করবে বা কমপক্ষে আপনাকে এটিকে কাজ করার জন্য খুব বেশি পরিশ্রমের প্রয়োজন হবে না।

আলগা সংযোগ সম্পর্কে কথা বলার সময় আমাদের উদ্বেগের পৃথকীকরণের কথা উল্লেখ করা উচিত। আপনি যদি কোনও এমভি * আর্কিটেকচারাল প্যাটার্ন ব্যবহার করে কোনও অ্যাপ্লিকেশন তৈরি করে থাকেন তবে আপনার কাছে সর্বদা একটি মডেল (গুলি) এবং একটি ভিউ থাকে have মডেল হ'ল আবেদনের ব্যবসায়ের অংশ। আপনি এটিকে বিভিন্ন অ্যাপ্লিকেশনগুলিতে পুনরায় ব্যবহার করতে পারেন, সুতরাং এটির কোনও একক অ্যাপ্লিকেশনটির ভিউ, যেখানে আপনি এটি দেখাতে চান তা মিলিয়ে নেওয়া ভাল ধারণা নয়, কারণ সাধারণত বিভিন্ন অ্যাপ্লিকেশনগুলিতে আপনার বিভিন্ন দৃষ্টিভঙ্গি থাকে। সুতরাং মডেল-ভিউ যোগাযোগের জন্য প্রকাশ / সাবস্ক্রাইব ব্যবহার করা ভাল ধারণা। যখন আপনার মডেল পরিবর্তন করে এটি একটি ইভেন্ট প্রকাশ করে, ভিউটি এটি ধরে এবং আপডেট হয়। আপনার প্রকাশ / সাবস্ক্রাইব থেকে কোনও ওভারহেড নেই, এটি আপনাকে ডিকোপলিংয়ের জন্য সহায়তা করে। একই পদ্ধতিতে আপনি উদাহরণস্বরূপ কন্ট্রোলারে আপনার অ্যাপ্লিকেশন যুক্তি রাখতে পারেন (এমভিভিএম, এমভিপি এটি ঠিক কোনও নিয়ামক নয়) এবং ভিউটিকে যতটা সম্ভব সহজ রাখতে পারেন। যখন আপনার দর্শন পরিবর্তন হয় (বা ব্যবহারকারী কোনও কিছুর উপরে ক্লিক করে) উদাহরণস্বরূপ এটি কেবল একটি নতুন ইভেন্ট প্রকাশ করে, নিয়ামক এটি ধরেন এবং কী করবেন তা সিদ্ধান্ত নেন। আপনি যদি সাথে পরিচিত হনএমভিসি প্যাটার্ন বা মাইক্রোসফ্ট টেকনোলজিতে এমভিভিএম সহ (ডাব্লুপিএফ / সিলভারলাইট) আপনি পর্যবেক্ষক প্যাটার্নের মতো প্রকাশ / সাবস্ক্রাইব সম্পর্কে ভাবতে পারেন । এই পদ্ধতির ব্যাকবোন.জেএস, নকআউট.জেএস (এমভিভিএম) এর মতো ফ্রেমওয়ার্কগুলিতে ব্যবহৃত হয়।

এখানে একটি উদাহরণ:

//Model
function Book(name, isbn) {
    this.name = name;
    this.isbn = isbn;
}

function BookCollection(books) {
    this.books = books;
}

BookCollection.prototype.addBook = function (book) {
    this.books.push(book);
    $.publish('book-added', book);
    return book;
}

BookCollection.prototype.removeBook = function (book) {
   var removed;
   if (typeof book === 'number') {
       removed = this.books.splice(book, 1);
   }
   for (var i = 0; i < this.books.length; i += 1) {
      if (this.books[i] === book) {
          removed = this.books.splice(i, 1);
      }
   }
   $.publish('book-removed', removed);
   return removed;
}

//View
var BookListView = (function () {

   function removeBook(book) {
      $('#' + book.isbn).remove();
   }

   function addBook(book) {
      $('#bookList').append('<div id="' + book.isbn + '">' + book.name + '</div>');
   }

   return {
      init: function () {
         $.subscribe('book-removed', removeBook);
         $.subscribe('book-aded', addBook);
      }
   }
}());

আরেকটি উদাহরণ. আপনি যদি এমভি * পদ্ধতির পছন্দ না করেন তবে আপনি কিছুটা আলাদা ব্যবহার করতে পারেন (আমি যেটির পরবর্তী এবং শেষটি উল্লিখিত করব তার মধ্যে একটি ছেদ রয়েছে)। বিভিন্ন মডিউলটিতে কেবল আপনার অ্যাপ্লিকেশনটি কাঠামো করুন। উদাহরণস্বরূপ টুইটারে দেখুন।

টুইটার মডিউল

আপনি যদি ইন্টারফেসটি দেখেন তবে আপনার কাছে সহজভাবে বিভিন্ন বাক্স রয়েছে। আপনি প্রতিটি বাক্সকে আলাদা মডিউল হিসাবে ভাবতে পারেন। উদাহরণস্বরূপ আপনি একটি টুইট পোস্ট করতে পারেন। এই ক্রিয়াটির জন্য কয়েকটি মডিউল আপডেট হওয়া দরকার। প্রথমত এটিতে আপনার প্রোফাইল ডেটা (উপরের বাম বাক্স) আপডেট করতে হবে তবে এটিতে আপনার টাইমলাইনটি আপডেট করতে হবে। অবশ্যই, আপনি উভয় মডিউলের জন্য রেফারেন্স রাখতে পারেন এবং তাদের সর্বজনীন ইন্টারফেস ব্যবহার করে এগুলি পৃথকভাবে আপডেট করতে পারেন তবে কেবল একটি ইভেন্ট প্রকাশ করা সহজ (এবং আরও ভাল)। এটি আলগা দম্পতির কারণে আপনার অ্যাপ্লিকেশনটির পরিবর্তনটিকে আরও সহজ করে তুলবে। আপনি যদি নতুন মডিউল বিকাশ করেন যা নতুন টুইটের উপর নির্ভর করে আপনি কেবল "প্রকাশিত টুইট" ইভেন্টটির সদস্যতা নিতে এবং এটি পরিচালনা করতে পারেন। এই পদ্ধতির খুব দরকারী এবং আপনার অ্যাপ্লিকেশন খুব decoupled করতে পারেন। আপনি খুব সহজেই আপনার মডিউলগুলি পুনরায় ব্যবহার করতে পারেন।

এখানে সর্বশেষ পদ্ধতির একটি প্রাথমিক উদাহরণ দেওয়া হয়েছে (এটি মূল টুইটার কোড নয় এটি আমার দ্বারা নিখুঁত একটি নমুনা):

var Twitter.Timeline = (function () {
   var tweets = [];
   function publishTweet(tweet) {
      tweets.push(tweet);
      //publishing the tweet
   };
   return {
      init: function () {
         $.subscribe('tweet-posted', function (data) {
             publishTweet(data);
         });
      }
   };
}());


var Twitter.TweetPoster = (function () {
   return {
       init: function () {
           $('#postTweet').bind('click', function () {
               var tweet = $('#tweetInput').val();
               $.publish('tweet-posted', tweet);
           });
       }
   };
}());

এই পদ্ধতির জন্য নিকোলাস জাকাসের একটি দুর্দান্ত আলোচনা আছে । এমভি * এর জন্য আমার জানা সেরা নিবন্ধ এবং বই অ্যাডি ওসমানী প্রকাশ করেছেন ।

ত্রুটিগুলি: আপনার প্রকাশ / সাবস্ক্রাইব অতিরিক্ত ব্যবহার সম্পর্কে সতর্ক থাকতে হবে। যদি আপনি শত শত ইভেন্ট পেয়ে থাকেন তবে এগুলি সমস্ত পরিচালনা করতে খুব বিভ্রান্তিকর হয়ে উঠতে পারে। আপনি যদি নেমস্পেসিংটি ব্যবহার করছেন না (বা এটি সঠিকভাবে ব্যবহার না করছেন) তবে আপনার সংঘর্ষও হতে পারে। মধ্যস্থতাকারীর একটি উন্নত বাস্তবায়ন যা দেখতে অনেকটা প্রকাশ / সাবস্ক্রাইবের মতো দেখাচ্ছে এখানে https://github.com/ajacksified/Mediator.js পাওয়া যাবে । এতে নেমস্পেসিং রয়েছে এবং ইভেন্ট "বুদবুদ" এর মতো বৈশিষ্ট্য রয়েছে যা অবশ্যই বাধাগ্রস্ত হতে পারে। প্রকাশ / সাবস্ক্রাইব করার আরেকটি অপূর্ণতা হ'ল হার্ড ইউনিট টেস্টিং, মডিউলগুলির বিভিন্ন ফাংশনকে আলাদা করে আলাদাভাবে পরীক্ষা করা কঠিন হতে পারে।


3
আপনাকে ধন্যবাদ, এটি উপলব্ধি করে। আমি এমভিসি প্যাটার্নের সাথে পরিচিত কারণ আমি এটি পিএইচপি দিয়ে সর্বদা ব্যবহার করি, তবে ইভেন্ট-চালিত প্রোগ্রামিংয়ের ক্ষেত্রে আমি এটি সম্পর্কে ভাবি নি। :)
ম্যাক্যাথ

2
এই বর্ণনার জন্য ধন্যবাদ। সত্যিই ধারণাটি সম্পর্কে আমার মাথা গুটিয়ে রাখতে সহায়তা করেছে।
ফ্লাইবার ভাল

1
এটি একটি দুর্দান্ত উত্তর। এটি আপ-ভোটিংটি আটকাতে পারিনি :)
নাভিদ বাট

1
দুর্দান্ত ব্যাখ্যা, একাধিক উদাহরণ, আরও পড়ার পরামর্শ। একজন ++,।
কারসন

16

মূল লক্ষ্য কোডের মধ্যে সংযোগ হ্রাস করা। এটি কিছুটা ইভেন্ট ভিত্তিক চিন্তার উপায়, তবে "ইভেন্টগুলি" কোনও নির্দিষ্ট বস্তুর সাথে আবদ্ধ নয়।

আমি নীচে কিছু সিউডো কোডে একটি বড় উদাহরণ লিখব যা জাভাস্ক্রিপ্টের মতো দেখাচ্ছে।

ধরা যাক আমাদের একটি ক্লাস রেডিও এবং একটি ক্লাস রিলে রয়েছে:

class Relay {
    function RelaySignal(signal) {
        //do something we don't care about right now
    }
}

class Radio {
    function ReceiveSignal(signal) {
        //how do I send this signal to other relays?
    }
}

যখনই রেডিও একটি সংকেত পায়, আমরা কোনও উপায়ে বার্তাটি রিলে করতে অনেকগুলি রিলে চাই। রিলে সংখ্যা এবং প্রকার পৃথক হতে পারে। আমরা এটি এর মতো করতে পারি:

class Radio {
    var relayList = [];

    function AddRelay(relay) {
        relayList.add(relay);
    }

    function ReceiveSignal(signal) {
        for(relay in relayList) {
            relay.Relay(signal);
        }
    }

}

এটি কাজ করে। তবে এখন কল্পনা করুন আমরা রেডিও ক্লাস যে সংকেতগুলি পেয়েছি সেগুলির অংশ নিতে একটি আলাদা উপাদান চাই want

(দুঃখিত যদি সাদৃশ্যগুলি শীর্ষে না থাকে ...)

class Speakers {
    function PlaySignal(signal) {
        //do something with the signal to create sounds
    }
}

আমরা আবার প্যাটার্নটি পুনরাবৃত্তি করতে পারি:

class Radio {
    var relayList = [];
    var speakerList = [];

    function AddRelay(relay) {
        relayList.add(relay);
    }

    function AddSpeaker(speaker) {
        speakerList.add(speaker)
    }

    function ReceiveSignal(signal) {

        for(relay in relayList) {
            relay.Relay(signal);
        }

        for(speaker in speakerList) {
            speaker.PlaySignal(signal);
        }

    }

}

আমরা "সিগন্যাললিস্টনার" এর মতো একটি ইন্টারফেস তৈরি করে এটি আরও উন্নত করতে পারলাম, যাতে আমাদের কেবলমাত্র রেডিও ক্লাসে একটি তালিকা প্রয়োজন এবং আমাদের যে কোনও অবজেক্ট যা সিগন্যাল শুনতে চায় তা নিয়ে সর্বদা একই ফাংশনটি কল করতে পারি। তবে এটি এখনও ইন্টারফেস / বেস ক্লাস / ইত্যাদি এবং আমরা রেডিও শ্রেণীর যে সিদ্ধান্ত নেব তার মধ্যে একটি সংযোগ তৈরি করে। মূলত যখনই আপনি রেডিও, সিগন্যাল বা রিলে ক্লাসের কোনও পরিবর্তন করেন আপনাকে কীভাবে এটি সম্ভবত অন্যান্য দুটি শ্রেণিতে প্রভাব ফেলতে পারে সে সম্পর্কে আপনাকে ভাবতে হবে।

এখন আসুন অন্য কিছু চেষ্টা করুন। আসুন রেডিওমাস্ট নামে একটি চতুর্থ শ্রেণি তৈরি করি:

class RadioMast {

    var receivers = [];

    //this is the "subscribe"
    function RegisterReceivers(signaltype, receiverMethod) {
        //if no list for this type of signal exits, create it
        if(receivers[signaltype] == null) {
            receivers[signaltype] = [];
        }
        //add a subscriber to this signal type
        receivers[signaltype].add(receiverMethod);
    }

    //this is the "publish"
    function Broadcast(signaltype, signal) {
        //loop through all receivers for this type of signal
        //and call them with the signal
        for(receiverMethod in receivers[signaltype]) {
            receiverMethod(signal);
        }
    }
}

এখন আমাদের একটি প্যাটার্ন রয়েছে যা সম্পর্কে আমরা সচেতন এবং যতক্ষণ না তারা ক্লাসের যেকোন সংখ্যা এবং ধরণের জন্য এটি ব্যবহার করতে পারি:

  • রেডিওমাস্ট সম্পর্কে সচেতন (ক্লাসটি সমস্ত বার্তা প্রেরণ করছে)
  • বার্তা প্রেরণ / গ্রহণের জন্য পদ্ধতি স্বাক্ষর সম্পর্কে সচেতন

সুতরাং আমরা রেডিও ক্লাসটিকে এর চূড়ান্ত, সহজ আকারে পরিবর্তন করি:

class Radio {
    function ReceiveSignal(signal) {
        RadioMast.Broadcast("specialradiosignal", signal);
    }
}

এবং আমরা স্পিকার এবং এই ধরণের সংকেতের জন্য রেডিওমাস্টের রিসিভার তালিকায় রিলে যুক্ত করি:

RadioMast.RegisterReceivers("specialradiosignal", speakers.PlaySignal);
RadioMast.RegisterReceivers("specialradiosignal", relay.RelaySignal);

এখন স্পিকার এবং রিলে ক্লাসের কোনও কিছুর শূন্য জ্ঞান রয়েছে কেবলমাত্র তাদের কাছে এমন পদ্ধতি রয়েছে যা একটি সিগন্যাল পেতে পারে এবং রেডিও ক্লাসটি প্রকাশক হওয়ায় রেডিওমাস্ট সম্পর্কে সচেতন যে এটি সংকেত প্রকাশ করে। এটি একটি বার্তা-পাসিং সিস্টেম যেমন প্রকাশ / সাবস্ক্রাইব ব্যবহার করে তা ব্যবহার করার বিষয়


সত্যিই দুর্দান্ত একটি দৃ concrete় উদাহরণ রয়েছে যা দেখায় যে 'সাধারণ' পদ্ধতি ব্যবহারের চেয়ে পাব / সাব প্যাটার্নটি কীভাবে কার্যকর করা যায়! ধন্যবাদ!
ম্যাককাথ

1
আপনাকে স্বাগতম! ব্যক্তিগতভাবে আমি প্রায়শই দেখতে পাই যে আমার মস্তিষ্ক যখন এটির জন্য সমাধান করে এমন একটি আসল সমস্যা বুঝতে না পারা পর্যন্ত নতুন প্যাটার্ন / পদ্ধতিগুলির ক্ষেত্রে আসে তখন 'ক্লিক' করে না। সাব / পাব প্যাটার্নটি আর্কিটেকচারের সাথে দুর্দান্ত যা ধারণাগতভাবে দৃ concept়ভাবে মিলিত হয়েছে তবে আমরা এখনও তাদের যথাসম্ভব আলাদা রাখতে চাই। একটি খেলা কল্পনা যেখানে আপনি বস্তুর শত শত সব উদাহরণস্বরূপ তাদের চারপাশে ঘটছে জিনিষ প্রতিক্রিয়া আছে আছে, এবং এই বস্তু সবকিছু হতে পারে: প্লেয়ার, বুলেট, গাছ, জ্যামিতি, GUI ইত্যাদি ইত্যাদি
অ্যান্ডার্স Arpi

3
জাভাস্ক্রিপ্টের classকীওয়ার্ড নেই। দয়া করে এই বাস্তবতার উপর জোর দিন। আপনার কোডটি সিউডো-কোড হিসাবে শ্রেণিবদ্ধ করে।
রব ডব্লু

আসলে ES6 এ একটি শ্রেণীর কীওয়ার্ড রয়েছে।
মিনকো গেচেভ

5

অন্যান্য উত্তরগুলি প্যাটার্নটি কীভাবে কাজ করে তা দেখানোর ক্ষেত্রে দুর্দান্ত কাজ করেছে। আমি সম্প্রতি এই প্যাটার্নটির সাথে কাজ করে যাচ্ছি বলে " পুরানো পথের মধ্যে কী ভুল? " এই অন্তর্নিহিত প্রশ্নটির সমাধান করতে চেয়েছিলাম এবং আমি দেখতে পেয়েছি এটি আমার চিন্তায় একটি পরিবর্তনের সাথে জড়িত।

কল্পনা করুন যে আমরা একটি অর্থনৈতিক বুলেটিনের সদস্যতা নিয়েছি। বুলেটিন একটি শিরোনাম প্রকাশ করেছে: " ডাউন জোসকে 200 পয়েন্ট কমিয়ে দিন "। এটি পাঠানো একটি বিজোড় এবং কিছুটা দায়িত্বজ্ঞানহীন বার্তা হবে। তবে, এটি প্রকাশিত হয়েছে: " এনরন আজ সকালে ১১ টি অধ্যক্ষ দেউলিয়া সুরক্ষার জন্য দায়ের করেছে ", তবে এটি আরও দরকারী বার্তা। নোট করুন যে বার্তাটি ডাউ জোন্সকে 200 পয়েন্ট হ্রাস করতে পারে তবে এটি অন্য একটি বিষয়।

কমান্ড প্রেরণ এবং সবেমাত্র ঘটেছে এমন কিছু পরামর্শ দেওয়ার মধ্যে পার্থক্য রয়েছে। এটি মাথায় রেখে, আপনার এখনই হ্যান্ডলারটিকে উপেক্ষা করে পাব / সাব প্যাটার্নের আসল সংস্করণটি নিন:

$.subscribe('iquery/action/remove-order', removeOrder);

$container.on('click', '.remove_order', function(event) {
    event.preventDefault();
    $.publish('iquery/action/remove-order', $(this).parents('form:first').find('div.order'));
});

ব্যবহারকারী-অ্যাকশন (একটি ক্লিক) এবং সিস্টেম-প্রতিক্রিয়া (একটি অর্ডার সরানো হচ্ছে) এর মধ্যে ইতিমধ্যে এখানে একটি অন্তর্নিহিত শক্তিশালী সংযোগ রয়েছে। কার্যকরভাবে আপনার উদাহরণে, ক্রিয়াটি একটি আদেশ দিচ্ছে। এই সংস্করণটি বিবেচনা করুন:

$.subscribe('iquery/action/remove-order-requested', handleRemoveOrderRequest);

$container.on('click', '.remove_order', function(event) {
    event.preventDefault();
    $.publish('iquery/action/remove-order-requested', $(this).parents('form:first').find('div.order'));
});

এখন হ্যান্ডলারটি ঘটেছে এমন আগ্রহের কিছুতে সাড়া দিচ্ছে, তবে কোনও আদেশ সরিয়ে নেওয়ার কোনও বাধ্যবাধকতা নেই। প্রকৃতপক্ষে, হ্যান্ডলারটি সমস্ত ধরণের কাজ করতে পারে কোনও অর্ডার অপসারণের সাথে সরাসরি সম্পর্কিত নয়, তবে কলিং অ্যাকশনের সাথে এখনও প্রাসঙ্গিক হতে পারে। উদাহরণ স্বরূপ:

handleRemoveOrderRequest = function(e, orders) {
    logAction(e, "remove order requested");
    if( !isUserLoggedIn()) {
        adviseUser("You need to be logged in to remove orders");
    } else if (isOkToRemoveOrders(orders)) {
        orders.last().remove();
        adviseUser("Your last order has been removed");
        logAction(e, "order removed OK");
    } else {
        adviseUser("Your order was not removed");
        logAction(e, "order not removed");
    }
    remindUserToFloss();
    increaseProgrammerBrowniePoints();
    //etc...
}

আইএমও এই প্যাটার্নটি তৈরি করতে একটি আদেশ এবং একটি বিজ্ঞপ্তির মধ্যে পার্থক্য একটি দরকারী পার্থক্য।


যদি আপনার শেষ 2 ফাংশন ( remindUserToFloss& increaseProgrammerBrowniePoints) পৃথক মডিউলগুলিতে অবস্থিত থাকে, তবে আপনি কি ঠিক সেখানে একে অপরের ঠিক পরে 2 টি ইভেন্ট প্রকাশ handleRemoveOrderRequestকরবেন বা সম্পন্ন হওয়ার পরে আপনার flossModuleকোনও browniePointsমডিউলটিতে একটি ইভেন্ট প্রকাশিত remindUserToFloss()হবে?
ব্রায়ান পি

4

যাতে আপনাকে হার্ডকোড পদ্ধতি / ফাংশন কলগুলি না করতে হয়, কে কেবল শোনেন সে যত্ন না করেই আপনি ইভেন্টটি প্রকাশ করেন। এটি আবেদনের 2 টি বিভিন্ন অংশের মধ্যে নির্ভরতা (বা কাপলিং, আপনি যে কোনও শব্দ পছন্দ করুন) হ্রাস করে গ্রাহক থেকে প্রকাশককে স্বাধীন করে তোলে।

উইকিপিডিয়া দ্বারা উল্লিখিত মিলনের কিছু অসুবিধা এখানে রয়েছে

শক্তভাবে সংযুক্ত সিস্টেমগুলি নিম্নলিখিত বিকাশের বৈশিষ্ট্যগুলি প্রদর্শন করে, যা প্রায়শই অসুবিধাগুলি হিসাবে দেখা যায়:

  1. একটি মডিউলে পরিবর্তন সাধারণত অন্যান্য মডিউলগুলির পরিবর্তনের প্রভাবকে চাপ দেয়।
  2. আন্তঃ-মডিউল নির্ভরতা বর্ধিত হওয়ার কারণে মডিউলগুলির সমাবেশে আরও বেশি প্রচেষ্টা এবং / অথবা সময় প্রয়োজন হতে পারে।
  3. একটি নির্দিষ্ট মডিউল পুনরায় ব্যবহার এবং / অথবা পরীক্ষা করা কঠিন হতে পারে কারণ নির্ভরশীল মডিউলগুলি অবশ্যই অন্তর্ভুক্ত করা উচিত।

ব্যবসায়ের ডেটা আবদ্ধ করার মতো কোনও বিষয় বিবেচনা করুন। এটি যখনই বয়স নির্ধারণ করা হয় তখন পৃষ্ঠাটি আপডেট করার জন্য হার্ড কোডিং পদ্ধতি কল রয়েছে:

var person = {
    name: "John",
    age: 23,

    setAge: function( age ) {
        this.age = age;
        showAge( age );
    }
};

//Different module

function showAge( age ) {
    $("#age").text( age );
}

এখন আমি showAgeফাংশনটিও অন্তর্ভুক্ত না করে ব্যক্তির বস্তুটি পরীক্ষা করতে পারি না । এছাড়াও, যদি আমাকে অন্য কিছু জিইউআই মডিউলেও বয়সটি দেখানোর দরকার হয় তবে আমাকে সেই পদ্ধতি কলটি হার্ডকোড করতে হবে .setAge, এবং এখন ব্যক্তি অবজেক্টে 2 অপ্রাসঙ্গিক মডিউলগুলির জন্য নির্ভরতা রয়েছে। আপনি যখন calls কলগুলি করা হচ্ছে দেখছেন এবং সেগুলি একই ফাইলে নেই তখনও এটি বজায় রাখা খুব কঠিন।

নোট করুন যে একই মডিউলটির ভিতরে আপনার অবশ্যই সরাসরি পদ্ধতি কল আসতে পারে। তবে ব্যবসায়ের ডেটা এবং অতিপরিসর গি আচরণ কোনও যুক্তিসঙ্গত মান দ্বারা একই মডিউলে থাকা উচিত নয়।


আমি এখানে 'নির্ভরতা' ধারণাটি বুঝতে পারি না; আমার দ্বিতীয় উদাহরণে নির্ভরতা কোথায়, এবং এটি আমার তৃতীয়টি থেকে কোথায় অনুপস্থিত? আমি আমার দ্বিতীয় এবং তৃতীয় স্নিপেটের মধ্যে কোনও ব্যবহারিক পার্থক্য দেখতে পাচ্ছি না - এটি আসল কারণ ছাড়াই ফাংশন এবং ইভেন্টের মধ্যে কেবল একটি নতুন 'স্তর' যুক্ত করবে বলে মনে হচ্ছে। আমি সম্ভবত অন্ধ হয়ে যাচ্ছি, তবে আমার মনে হয় আমার আরও পয়েন্টার দরকার। :(
ম্যাকথ ক্যাথ

1
আপনি কি কোনও নমুনা ব্যবহারের ক্ষেত্রে প্রদান করতে পারবেন যেখানে একই জিনিস সম্পাদন করে এমন কোনও ফাংশন তৈরি করার চেয়ে প্রকাশ / সাবস্ক্রাইব করা আরও উপযুক্ত হবে?
জেফরি সুইনি

@ ম্যাক্যাথ সোজা কথায়: তৃতীয় উদাহরণে, আপনি জানেন না বা এটি জানেন যে removeOrderএমনকি উপস্থিত রয়েছে, তাই আপনি এর উপর নির্ভরশীল হতে পারবেন না। দ্বিতীয় উদাহরণে, আপনাকে জানতে হবে।
ইসাইলিজা

আপনি এখনও এখানে বর্ণিত বিষয়গুলি সম্পর্কে আরও ভাল উপায় আছে বলে আমার মনে হলেও, আমি অন্তত নিশ্চিত যে এই পদ্ধতির উদ্দেশ্য রয়েছে, বিশেষত অন্যান্য বিকাশকারীদের প্রচুর পরিবেশে has +1
জেফরি সুইনি

1
@ ইসাইলিজা - আপনাকে ধন্যবাদ, আমি মনে করি আমি কিছুটা আরও ভাল বুঝতে পেরেছি সুতরাং ... আমি যদি গ্রাহককে পুরোপুরি সরিয়ে ফেলি তবে এটি ত্রুটি বা কোনও কিছু ঘটবে না, এটি কিছুই করবে না? এবং আপনি কি বলবেন যে আপনি কোনও ক্রিয়া সম্পাদন করতে চান এমন ক্ষেত্রে এটি কার্যকর হতে পারে তবে প্রকাশের সময় কোন ফাংশনটি সবচেয়ে প্রাসঙ্গিক তা অগত্যা জানাবেন না তবে গ্রাহক অন্যান্য বিষয়গুলির উপর নির্ভর করে পরিবর্তন করতে পারবেন?
ম্যাক্যাথ

1

পাবসব বাস্তবায়ন সাধারণত যেখানে দেখা যায় সেখানে দেখা যায় -

  1. বাস্তবায়নের মতো একটি পোর্টলেট রয়েছে যেখানে একাধিক পোর্টলেট রয়েছে যা ইভেন্ট বাসের সাহায্যে যোগাযোগ করে। এটি aync আর্কিটেকচার তৈরিতে সহায়তা করে।
  2. টাইট কাপলিং দ্বারা বিভক্ত একটি সিস্টেমে পাবসব এমন একটি প্রক্রিয়া যা বিভিন্ন মডিউলগুলির মধ্যে যোগাযোগে সহায়তা করে।

উদাহরণ কোড -

var pubSub = {};
(function(q) {

  var messages = [];

  q.subscribe = function(message, fn) {
    if (!messages[message]) {
      messages[message] = [];
    }
    messages[message].push(fn);
  }

  q.publish = function(message) {
    /* fetch all the subscribers and execute*/
    if (!messages[message]) {
      return false;
    } else {
      for (var message in messages) {
        for (var idx = 0; idx < messages[message].length; idx++) {
          if (messages[message][idx])
            messages[message][idx]();
        }
      }
    }
  }
})(pubSub);

pubSub.subscribe("event-A", function() {
  console.log('this is A');
});

pubSub.subscribe("event-A", function() {
  console.log('booyeah A');
});

pubSub.publish("event-A"); //executes the methods.

1

"দ্য মেন ফেসস অফ প্রকাশনা / সাবস্ক্রাইব" কাগজটি ভাল পঠিত এবং একটি বিষয় যা তারা জোর দিয়ে থাকে তা তিনটি "মাত্রায়" ডিকউপল হয়। এখানে আমার অপরিশোধিত সংক্ষিপ্তসার, তবে দয়া করে কাগজটিও রেফারেন্স করুন।

  1. স্থান decoupling। কথোপকথনকারী পক্ষগুলির একে অপরকে জানার দরকার নেই। কারা শুনছে, কারা শুনছে, বা ইভেন্টটি নিয়ে তারা কী করছে তা প্রকাশক জানেন না। গ্রাহকরা জানেন না কে এই ইভেন্টগুলি উত্পাদন করছে, কত প্রযোজক রয়েছে ইত্যাদি etc.
  2. সময় decoupling। কথোপকথনকারী পক্ষগুলিকে মিথস্ক্রিয়া চলাকালীন একই সময়ে সক্রিয় হওয়ার প্রয়োজন নেই। উদাহরণস্বরূপ, কোনও প্রকাশক কিছু ইভেন্ট প্রকাশ করার সময় কোনও গ্রাহক সংযোগ বিচ্ছিন্ন হয়ে থাকতে পারে, তবে এটি অনলাইনে এলে তা প্রতিক্রিয়া জানাতে পারে।
  3. সিঙ্ক্রোনাইজেশন ডিউপলিং। ইভেন্টগুলি উত্পাদন করার সময় প্রকাশকগুলিকে অবরুদ্ধ করা হয় না এবং গ্রাহকরা কলব্যাকের মাধ্যমে সংক্ষিপ্তভাবে অবহিত করা যেতে পারে যখনই তারা ইভেন্টটি সাবস্ক্রাইব করেছেন।

0

সহজ উত্তর আসল প্রশ্নটি একটি সহজ উত্তর খুঁজছিল। আমার চেষ্টা এখানে।

জাভাস্ক্রিপ্ট কোড ইভেন্টের নিজস্ব ইভেন্ট তৈরি করতে কোনও প্রক্রিয়া সরবরাহ করে না। সুতরাং আপনার প্রয়োজন এক ধরণের ইভেন্ট মেকানিজম। প্রকাশ / সাবস্ক্রাইব প্যাটার্ন এই প্রয়োজনটির জবাব দেবে এবং আপনার নিজের প্রয়োজন অনুসারে এমন একটি প্রক্রিয়া চয়ন করা আপনার উপর নির্ভর করবে।

এখন আমরা পাব / সাব প্যাটার্নের প্রয়োজন দেখতে পাচ্ছি, তারপরে আপনি কীভাবে আপনার পাব / উপ ইভেন্টগুলি পরিচালনা করবেন তার থেকে আলাদা করে আপনাকে ডিওএম ইভেন্টগুলি পরিচালনা করতে হবে? জটিলতা হ্রাস করার স্বার্থে এবং অন্যান্য ধারণা যেমন উদ্বেগের বিচ্ছিন্নতা (এসওসি) আপনি দেখতে পাচ্ছেন যে সবকিছু অভিন্ন হওয়ার সুবিধা রয়েছে।

সুতরাং বিদ্বেষজনকভাবে, আরও কোড উদ্বেগের আরও ভাল বিভাজন তৈরি করে, যা খুব জটিল ওয়েব পৃষ্ঠাগুলিতে ভাল স্কেল করে।

আমি আশা করি যে কেউ বিশদে না গিয়ে এটিকে যথেষ্ট ভাল আলোচনাটি পেয়েছেন।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.