অবজার্ভার ডিজাইন প্যাটার্ন  উইথ টাইপস্ক্রিপ্ট 
Tags: oop, designpattern, observerdesignpattern, typescript
Published: 2021-04-21 10:04:12

অবজার্ভার ডিজাইন প্যাটার্ন কি, কিভাবে কাজ করে এবং কেন ব্যবহার করবো তা বুঝার আগে চলুন কিছু সিনারিও দেখে আসি। 
অনেক ওয়েবসাইটে নিউজলেটার নামে একটা অপশন আমরা দেখে থাকি। আমরা যদি আমাদের ইমেইল দিয়ে সেটা সাবস্ক্রাইব করি তাহলে ঐ ওয়েবসাইটে নতুন কিছু কন্টেন্ট আপডেট হলে আমাদের কাছে নোটিফিকেশন আসে। তারপর আমরা সোশ্যাল মিডিয়ায় অনেক সেলেব্রিটি বা পেজকে ফলো করি। ফলো করার জন্য আমাদের ফলো অপশনে ক্লিক করতে হয়। ফলো করার পর যদি ঐ সেলেব্রিটি বা পেজ নতুন কিছু আপলোড করে তাহলে সব ফলোয়ারের কাছে নোটিফিকেশন চলে যায়। তাছাড়া আমরা অনেকেই লিঙ্কডইনে বিভিন্ন ক্রাইটেরিয়া সেট করে জব এলার্ট অপশন অন করে রাখি।যখনই কোনো নতুন জব কেউ পোস্ট করে লিঙ্কডইন তখন নোটিফাই করে।
যদি আমরা এই সবগুলো সিনারিওর দিকে তাকাই তাহলে একটা প্যাটার্ন দেখতে পাই। সবগুলোতেই আমাদেরকে ফলো, লাইক বা সাবস্ক্রাইব করে রাখতে হয় আর যখনই নতুন কিছু আসে তখনই সেটা সবার কাছে নোটিফিকেশন আকারে পৌঁছে যায়। তো যদি এই লাইক, ফলো বা সাবস্ক্রাইব অপশন না থাকতো তাহলে কি হতো। তখন ইউজার নতুন কিছু আসছে কি না সেটা দেখার জন্য বারবার কিছুক্ষন পরপর গিয়ে দেখা লাগতো যে নতুন কোনো কিছু আসছে কি না। তাছাড়া কেউ যদি লাইভ কিছু করে সেগুলো মিস হয়ে যাওয়ার সম্ভাবনা থেকে যায়।
উপরে যে যে সিনারিওগুলো দেখলাম এই সবগুলো সমস্যার সমাধান অবজার্ভার ডিজাইন প্যাটার্ন দিয়ে করা সম্ভব। তাহলে চলুন শুরু করি

উপরের প্রত্যেকটি সিনারিওতেই যদি আমরা খেয়াল করি তাহলে দেখবো ২টি অবজেক্ট আছে। একটি হলো সাবজেক্ট অবজেক্ট যেটা উপরের প্রথম সিনারিওতে ওয়েবসাইট, দ্বিতীয় সিনারিওতে সেলিব্রেটির প্রোফাইল বা পেজ আর তৃতীয় সিনারিওতে  লিঙ্কডইন। আর আরেকটা অবজেক্ট হলো ডিপেন্ডেন্সি অবজেক্ট বা অবজার্ভার যেটা উপরের তিনটি সিনারিওতেই ইউজার যারা লাইক, ফলো বা সাবস্ক্রাইব করে রাখে। অবজার্ভার প্যাটার্ন এই দুইটি অবজেক্ট এর মধ্যে ওয়ান টু মেনি রিলেশন তৈরি করে যাতে যখনই সাবজেক্টের মধ্যে কোনো নতুন চেঞ্জ আসবে সাথে সাথে ওই সাবজেক্টের সব ডিপেন্ডেন্সি অবজেক্টকে নোটিফাই এবং আপডেট করে ফেলবে অটোম্যাটিকেলি। 


তাহলে এই সাবজেক্টের কাজ কি কি সেটা একটু চিন্তা করি। নতুন ইউজার এড করার জন্য সাবজেক্টের একটা মেথড লাগবে যেটা দিয়ে ইউজার লাইক, ফলো বা সাবস্ক্রাইব করতে পারে। একইভাবে আরেকটি অপশন লাগবে যেটা দিয়ে আনলাইক, আনফলো বা আনসাবস্ক্রাইব করতে পারবে। আরেকটি মেথড লাগবে সবাইকে নোটিফাই করার জন্য যাতে যখনই নতুন কিছু আপডেট আসবে তখনই এই মেথড কল করে সবাইকে নোটিফাই করা যায়। এই তিনটি কাজ করার জন্য আমরা তিনটি মেথড ডিফাইন করতে পারি। ক্লাস ডায়াগ্রামে আমরা সাবজেক্ট ইন্টারফেস দিয়ে এই তিনটি মেথড ডিফাইন করে দিয়েছি।
এখন আসি ডিপেন্ডেন্সি অবজেক্ট বা অবজার্ভারের কাজ কি।আমাদের অবজার্ভারকে বলে দিতে হবে সাবজেক্ট কিভাবে অবজার্ভারকে নোটিফাই করবে। এই কাজটি করার জন্য অবজার্ভারের একটি আপডেট মেথড লাগবে যেটা ব্যবহার করে সাবজেক্ট তাকে নোটিফাই করবে। ক্লাস ডায়াগ্রামে আমরা অবজার্ভার ইন্টারফেস দিয়ে এই মেথড ডিফাইন করে দিয়েছি।

আমি এই ক্লাস ডায়াগ্রামটা নিয়েছি হেড ফার্স্ট ডিজাইন প্যাটার্ন বই থেকে যেটা ডিজাইন প্যাটার্নের জন্য টপ লিস্টেড বইগুলোর মধ্যে একটি।
![Class Diagram](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qa2ulogkq0lg33ka53gw.png)
উপরের ডায়াগ্রামে সাবজেক্ট ইন্টারফেসের মধ্যে উপরে বর্ণনা করা তিনটি মেথড ডিফাইন করা আছে আর অবজার্ভার ইন্টারফেসে উপরে বর্ণনা করা একটি মেথড ডিফাইন করা আছে। এখন আসি ConcreteSubject ক্লাস নিয়ে। উপরের ডায়াগ্রাম থেকে দেখাই যাচ্ছে এটা সবসময় সাবজেক্ট ইন্টারফেসকে ইমপ্লিমেন্ট করবে। তখন তাকে সাবজেক্ট ইন্টারফেসে ডিফাইন করা তিনটি মেথডকেই ইমপ্লিমেন্ট করতে হবে। notifyObserver() মেথড দিয়ে সব অবজার্ভারকে নোটিফাই করবে। সেটার জন্য notifyObserver() মেথডের ভিতরে আমরা অবজার্ভার ইন্টারফেসের update() মেথড কল করে নোটিফাই এবং আপডেট করে ফেলব। আর ConcreteObserver() অবজার্ভার ইন্টারফেসকে ইমপ্লিমেন্ট করবে।  তখন তাকে অবজার্ভার ইন্টারফেসে ডিফাইন করা update() মেথডকেই ইমপ্লিমেন্ট করতে হবে।

##ইমপ্লিমেন্টেশন
এখন চলুন উপরের প্রথম সিনারিওটা ইমপিমেন্ট করি। নিউজলেটার সিস্টেম ইমপিমেন্ট করার জন্য আমাদের একটি নিউসলেটার পাবলিশার লাগবে যেটা উপরের সাবজেক্ট ইন্টারফেসকে ইমপিমেন্ট করবে। আর নোটিফিকেশন রিসিভ করার জন্য ডিপেন্ডেন্সি অবজেক্ট বা অবজার্ভার লাগবে যেটা অবজার্ভার ইন্টারফেসকে ইমপিমেন্ট করবে। 

প্রথমেই আমরা সাবজেক্ট আর অবজার্ভার ইন্টারফেস তৈরি করে ফেলি। নিচে সাবজেক্ট আর অবজার্ভার ইন্টারফেস তৈরি করে ফেললাম। 
`Subject.ts`
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/78k77a7wbr91r8ljqogn.png)
`Observer.ts`
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1lxz4si7d8wxxztqxccn.png)

নিউসলেটার পাবলিশারের জন্য NewsLetterPublisher ক্লাসটি তৈরি করলাম।
`NewsLetterPublisher.ts`
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vu19kk0mcv8ufrreyfnt.png)
পাবলিশারে সব অবজার্ভারকে রাখার জন্য আমরা একটি অ্যারে ডিফাইন করলাম। যেহেতু এই ক্লাসটি সাবজেক্টকে ইমপিমেন্ট করেছে তাই সাবজেক্টে ডিফাইন করা তিনটি মেথডকেই এখানে ইমপিমেন্ট করা হয়েছে। আরেকটি নতুন মেথড newChangeToSend() ইমপিমেন্ট করা হয়েছে যাতে নতুন কোনো আপডেট আসলে এই মেথড এর ভিতরে notifyObserver() মেথড কল করে সবাইকে নোটিফাই করা যায়। 

নিউসলেটার রিসিভারের জন্য NewsLetterReceiver ক্লাসটি তৈরি করলাম যেটা অবজার্ভারকে ইমপ্লিমেন্ট করেছে। যখনি নতুন কোন অবজার্ভার তৈরি করতে হবে তখন একটা ইমেইল দিতে হবে। 
`NewsLetterReceiver.ts`
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yk732q22d0z1oy6002jf.png)

এখন একটা মেইন ক্লাস লিখে ফেললাম টেস্ট করার জন্য।
`main.ts`
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2xcdq8dglqh4whufx471.png)
প্রথমে আমরা একটা পাবলিশার তৈরি করলাম। রিসিভার আর রিসিভার১ নামে দুইটি  অবজার্ভার তৈরি করলাম যারা ওই পাবলিশারকে সাবস্ক্রাইব করে রেখেছে। যখনি পাবলিশার নতুন কিছু আপডেট করলো তখন এই দুইজনের কাছে নোটিফিকেশন যাবে। তারপরে রিসিভার১ আনসাবস্ক্রাইব করার পর তার কাছে আর যদি  পাবলিশার নতুন কিছু আপডেট করে তাহলে তার নোটিফিকেশন যাবে না।নিচে আউটপুট দেখা যাচ্ছে। রিসিভার১ আনসাবস্ক্রাইব করার পর তার কাছে আর নোটিফিকেশন যায়নি।
`Output`
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vqw7sg9pnqpcpoqrzx53.png)
উপরের ইমপ্লিমেন্টেশনের সম্পূর্ণ কোড পাওয়া যাবে এই [লিংকে](https://github.com/ashrafhussain17/Design_Pattern/tree/master/ObserverPattern/newsletter) 

এখন আসি এই অবজার্ভার প্যাটার্নের সুবিধাগুলু কি কি। অবজার্ভার প্যাটার্নের একটি ভালো সুবিধা হচ্ছে এটা **SOLID** এর **O** মানে **Open Close Principle** কে কভার করে। তাছাড়া এটা হাই কুহেসিভ আর লো কাপলিং কোড লিখতে সাহায্য করে। এখানে সাবজেক্ট তার ডিপেন্ডেন্সি অবজেক্ট বা অবজার্ভারের ইমপ্লিমেন্টেশন সম্পর্কে কিছুই জানে না কিন্তু সে আপডেট করে ফেলে। তাছাড়া এটা **JAVA** ও **JAVASCRIPT** ল্যাঙ্গুয়েজের বেশ কিছু জায়গায় ব্যাবহার করা হয়েছে। যেমন **JDK** তে, **Socket** প্রোগ্রামিংয়ে। তাছাড়া আরও অনেক অনেক লাইব্রেরিতে এই প্যাটার্ন ব্যাবহার করা হয়।   
নোটস: উপরে অনেক জায়গায় পাবলিশ সাবস্ক্রাইব টার্মটি উল্লেখ করেছি। হেড ফার্স্ট ডিজাইন প্যাটার্ন বইয়েও অনেক জায়গায় এটাই ব্যাবহার করেছে কিন্তু **Publish-Subscribe** বা **PUB-SUB** নামে আরেকটি প্যাটার্ন আছে যেটা অবজার্ভার প্যাটার্ন থেকে কিছুটা ডিফারেন্ট। এই দুই প্যাটার্নের আইডিয়া অলমোস্ট সেম । **Publish-Subscribe** প্যাটার্ন ইভেন্ট বেসড কমিউনিকেশনে যেমন **Nats Streaming Server** বা **Apache Kafka** এগুলাতে ব্যাবহার করা হয়।