অবজেকটিভ সি প্রোগ্রামিং ল্যাঙ্গুয়েজের একটা গুরুত্বপূর্ণ অংশ হল প্রোটোকল ও ডেলিগেশন। প্রথমে খাঁটি বাংলায় ডেলিগেট ব্যাপারটা চিন্তা করা যাক। ডেলিগেট কথাটার অর্থ হল প্রতিনিধি। অর্থাৎ ধরা যাক, পৃথিবীর দুই সুপার পাওয়ার আমেরিকা ও রাশিয়ার মধ্যে ঝামেলা লেগেছে। এখন আমেরিকার প্রেসিডেন্ট বারাক ওবামা ও রাশিয়ার প্রেসিডেন্ট ভ্লাদিমির পুতিন যদি সেটার সমাধান নিয়ে একসাথে বসতে চান সেখানে অনেক সমস্যা ও অনেক কাঠখড় পুড়িয়ে বসতে হবে। এর চেয়ে সহজ বুদ্ধি হল, প্রেসিডেন্ট ওবামার পক্ষ একজন প্রতিনিধি ও প্রেসিডেন্ট পুতিনের পক্ষের একজন প্রতিনিধি একসাথে বসে সমস্যা নিয়ে আলোচনা করে কিছু প্রস্তাবনা নিজ নিজ দেশের নীতিনির্ধারকদের কাছে সমাধানের জন্য পৌঁছে দিতে পারেন। এটাই হল ডেলিগেশন ও এই বুদ্ধিটা একটা প্রোটোকল। এখন দেখা যাক, আমাদের জন্য ডেলিগেশন ব্যাপারটা কি রকম।
প্রোটোকল হল একটা ক্লাসের ভিতর কয়েকটা মেথড এর সমন্বয়ে তৈরি একটা গ্রুপ , এখন অন্য কোন ক্লাস যদি প্রোটোকল আছে এমন কোন ক্লাস ব্যবহার করতে চায় তবে তাকে ঐ ক্লাসের প্রোটোকলের ভিতর যে মেথডগুলো আছে সেগুলো ইমপ্লিমেন্ট করতে হবে। নিচের উদাহরণে দেখানো হয়েছে কিভাবে প্রোটোকল লিখতে হয়। প্রোটোকল শুরু হয় @protocol কিওয়ার্ড দিয়ে আর অন্য সবকিছুর মত @end দিয়ে শেষ হয়। যেহেতু প্রোটোকলের প্রয়োজনটা কিছু মেথডের জন্যই তাই অবশ্যই কিছু মেথড থাকবে। এখন একটা প্রোটোকলের সব মেথড আমাদের সবসময় দরকার নাও লাগতে পারে। এজন্য প্রোটোকলের ভিতর যে মেথডগুলো আমাদেরকে অবশ্যই আমাদের ক্লাসে ইমপ্লিমেন্ট করতে হবে সেগুলোকে @required কিওয়ার্ড এর পরে লিখতে হবে। অনুরূপভাবে যে মেথডগুলো আমাদের জন্য আবশ্যিক নয়, অর্থাৎ আমাদের দরকার হতেও পারে না পারে সেগুলোর আগে @optional ব্যবহার করা হয়।
এবার আমরা আমাদের প্রোটোকলযুক্ত ক্লাসের ইন্টারফেস ফাইলটা দেখি। দেখা যাচ্ছে আমরা , id টাইপের একটা ক্লাস ভ্যারিয়েবল ডিক্লেয়ার করেছি। অবজেক্টিভ সি তে id হল একটা বিশেষ টাইপ যেটা দিয়ে যেকোনো প্রকারের অবজেক্টিভ সি অবজেক্টের রেফারেন্স রাখা যায়। আমরা শুরুতেই প্রতিনিধির কি দরকার সেটা নিয়ে কথা বলেছি। এখন আমরা জানি আমাদের এই প্রোটোকলকে যেকোনো ক্লাসই ব্যবহার করতে পারে, কাজেই আমরা এখানে id টাইপ ব্যবহার করছি যাতে করে কোন ক্লাস আমার প্রোটোকল ব্যবহার করছে সেটা নিয়ে আমার মাথাব্যাথা না থাকে।
আরও একটা সমস্যা আছে, আমাদের যে প্রোটোকল সেটার মেথডগুলো আমাদের ক্লাসে শুধু ইমপ্লিমেন্ট করলেই হবেনা, এটাকে আমাদের প্রয়োজনমত কাজ করানোর জন্য তাকে জানাতেও হবে যে আমি তোমাকে ব্যবহার করছি। এই জানানোর জন্য দরকার প্রতিনিধি বা ডেলিগেট। এটাই এখানে id delegate অবজেক্ট ও – (void) SetDelegate : (id) newDelegate মেথডের কাজ। এখন নিচে দেখা যাক ClassWithProtocol ক্লাসের ইমপ্লিমেন্টেশন কেমন হয়।
এখন আমরা আরেকটা ক্লাস লিখব যেটা আমাদের লেখা MyProtocol কে ইমপ্লিমেন্ট করবে। সেটার জন্য আমাদের ক্লাসের ইন্টারফেস ফাইলে ক্লাসের নাম ও সুপারক্লাসের নামের পর একটা অ্যাংগেল ব্রাকেটের ভিতর প্রোটোকলের নাম নিখতে হয়। নিচের কোডটা দেখলে বোঝা যাবে। জেনে রাখা দরকার, একটা ক্লাস যত খুশি প্রোটোকল ইমপ্লিমেন্ট করতে পারে। যদি ক্লাস একের বেশি প্রোটোকল ইমপ্লিমেন্ট করে তাহলে অ্যাংগেল ব্রাকেটের ভিতর প্রোটোকলগুলোর নামের মাঝে কমা দিতে হবে।
আমাদের ক্লাসের ইমপ্লিমেন্টেশনে আমাদেরকে প্রোটোকলের সকল @required মেথড এবং প্রয়োজনমত @optional মেথড ইমপ্লিমেন্ট করতে হবে। এখানে আমাদের প্রোটোকলের ক্লাসের কাছে আমার ক্লাসের রেফারেন্স দিতে হবে ডেলিগেটের মাধ্যমে, যেটা এখানে [object SetDelegate:self]; মেথড কল করে করা হয়েছে।
এখন আমরা যদি এটাকে যদি এভাবে রান করি তাহলে কনসোলে নিচের মত আউটপুট আসবে।
এখন আসি প্রোটোকল ও ডেলিগেশনের বাস্তব ব্যবহারে। অবজেক্টিভ সিতে এটা অনেক কাজে অনেকভাবেই ব্যবহার করা হয়, একটা বিশেষ ব্যবহার হল কলব্যাক মেথড । ধরা যাক, আমাদের ক্লাস ইন্টারনেট থেকে একটা ফাইল ডাউনলোড করে। আমরা চাই যখন ডাউনলোড শেষ হয় আমাদের ক্লাস যেন জানতে পারে যে ডাউনলোড শেষ যাতে করে সে ডাউনলোড করা ফাইল নিয়ে তার পরবর্তী কাজ শুরু করতে পারে। কিংবা আরেকটা উদাহরণ হতে পারে, ধরা যাক আমাদের আইফোন অ্যাপে আমরা একটা স্ক্রিন থেকে আরেকটাতে গেলাম, আমার দ্বিতীয় স্ক্রিন থেকে আগেরটাতে কোন ডেটা পাঠানোর দরকার হতে পারে। সেক্ষেত্রেও আমাদের প্রোটোকল ও ডেলিগেট প্রয়োজন হবে।
আজকে এ পর্যন্তই , আগামী লেকচারে আবার দেখা হবে 🙂