প্রোটোকল

ভূমিকাঃ অবজেক্টিভ সি তে আপনি প্রোটোকল নামের একধরনের ফিচার ডিফাইন করতে পারবেন যেখানে কিছু মেথড ডিক্লেয়ার করা যেতে পারে যে মেথডগুলো বিশেষ পরিস্থিতিতে ব্যবহার করা যায়। যে ক্লাস ওই প্রোটোকলকে মেনে চলবে সেই ক্লাসে ওই প্রোটোকলের মেথড গুলোকে ইমপ্লিমেন্ট করা হয়। আমরা নিচে যে উদাহরণ দেখবো সেখানে Food ক্লাসটি MakeProtocol কে মেনে চলবে, যে প্রোটোকলে processCompleted মেথডটি ডিক্লেয়ার করা আছে, যে মেথডের কাজ হচ্ছে খাবার তৈরি শেষ হয়ে গেলে ওই Food ক্লাসকে তা জানিয়ে দেয়া। অর্থাৎ, যেকোনো জায়গা থেকে Food ক্লাসের মধ্যে ইমপ্লিমেন্ট/ডিফাইন করা processCompleted মেথডকে কল করা। processCompleted মেথডটিকে অবশ্যই Food ক্লাসে ইমপ্লিমেন্ট করতে হবে। আর তাই এই ঘটনা অবশ্যই ঘটতে বাধ্য যে, Food ক্লাসের processCompleted মেথডটিকে এক্সিকিউট করা যাবেই।

সিনট্যাক্সঃ

@protocol ProtocolName
@required
// list of required methods
@optional
// list of optional methods
@end

@required কিওয়ার্ডের নিচে থাকা মেথড/মেথডগুলোকে কে অবশ্যই সেই ক্লাসে ইমপ্লিমেন্টেড থাকতে হবে যে ক্লাস এই প্রোটোকলকে মেনে চলবে (conform)। আর @optional কিওয়ার্ডের নিচে থাকা মেথড/মেথডগুলোকে কে সেই ক্লাসে ইমপ্লিমেন্ট না করলেও চলবে। নিচের মত করে একটি ক্লাস যেকোনো একটি প্রোটোকলকে মেনে চলার ব্যপারে অঙ্গীকারাবদ্ধ হতে পারে।

@interface MyClass : NSObject <MyProtocol>
...
@end

প্রোটোকল এর প্রয়োগঃ এখন আপনার প্রজেক্ট এর সাথে নিচের ফাইলগুলো মিলিয়ে একটি পরিষ্কার প্রজেক্ট সাজিয়ে ফেলুন। তারপর আমরা ওই প্রজেক্টে প্রোটোকল এর ব্যবহারটা বুঝতে চেষ্টা করব।

// MakeProtocol.h

#import <Foundation/Foundation.h>

@protocol MakeProtocol <NSObject>

- (void)processCompleted;

@end

এই আমাদের বানানো processCompleted মেথড বিশিষ্ট একটি প্রোটোকল। যে ক্লাস এই প্রোটোকলকে মেনে চলবে তাকে অবশ্যই processCompleted মেথড ইমপ্লিমেন্ট করতে হবে।

// Make.h

#import <Foundation/Foundation.h>

@interface Make : NSObject

@property (unsafe_unretained) id delegate;

- (void) startCooking;

@end

এটি হচ্ছে main এবং Food এর কর্মকাণ্ডের মধ্যবর্তী কিছু কাজের জন্য একটি ক্লাস এর ইন্টারফেস যেখানে একটি প্রোপার্টি এবং একটি মেথড ডিক্লেয়ার করা আছে। delegate প্রোপার্টিটিতে কোন ক্লাসের প্রতিনিধিত্ব সেট করা যায়। startCooking একটি সাধারণ মেথড যার বিস্তারিত একটু পরে Make এর ইমপ্লিমেন্টেশন থেকেও বোঝা যাবে।

// Make.m

#import "Make.h"
#import "MakeProtocol.h"

@implementation Make

- (void)startCooking{
    NSLog(@"Cooking Started!");

    // The following delegate property refers to
    // the Food class's object which was set from inside
    //// placeOrder
    // method of Food.

    // Then, a fact is also assured here that, the
    //// processCompleted
    // method will must be called from here which will
    // let the calling object know about its completion.

    [_delegate processCompleted];
}

@end

startCooking মেথডের শুরুতে আমরা একটি ম্যাসেজ প্রিন্ট করছি যে কুকিং শুরু হয়ে গেছে। তারপর আমরা এই ক্লাসের ডেলিগেট প্রোপার্টি ব্যবহার করে processCompleted ডেলিগেট মেথডকে কল করছি। এটা মূলত Food ক্লাসের মধ্যে থাকা processCompleted কেই কল করছে কারন একটু নিচেই আমরা দেখবো যে, Food ক্লাসের মধ্যের একটি মেথডের মাধ্যমে আমরা এই Make ক্লাসের ডেলিগেটটি সেট করছি অর্থাৎ Make ক্লাসের ডেলিগেট মূলত Food ক্লাসের অবজেক্ট হিসেবেই কাজ করছে।

// Food.h

#import <Foundation/Foundation.h>
#import "MakeProtocol.h"

@interface Food : NSObject <MakeProtocol>

- (void)placeOrder;

@end

উপরের কোড ব্লকে দেখতে পাচ্ছেন কিভাবে Food ক্লাসটি MakeProtocol নামের প্রোটোকলকে মেনে চলার ব্যাপারে নির্ধারিত হচ্ছে। সুপার ক্লাসের নামের পরে < MakeProtocol > এভাবে প্রোটোকল এর নাম ঠিক করে দেয়া যায়। যদি এই ক্লাসটি একাধিক প্রোটোকলকে মেনে চলতে চায় তাহলে < MakeProtocol, AnotherProtocol, ... > এভাবে প্রোটোকল লিস্ট ঠিক করে দেয়া যায়। এই ক্লাসে placeOrder নামের একটি সাধারণ মেথডও আছে যেখান থেকেই আসলে খাবারের অর্ডার নিয়ে কুকিং শুরু সহ বাকি কাজগুলো হয়।

// Food.m

#import "Food.h"
#import "Make.h"

@implementation Food

- (void)placeOrder{
    Make *make = [[Make alloc]init];
    make.delegate = self;
    [make startCooking];
}

-(void)processCompleted{
    NSLog(@"Cooking Process Completed & this method has been called!");
}

@end
// main.m

#import <Foundation/Foundation.h>
#import "Food.h"

int main(int argc, const char * argv[])
{

    @autoreleasepool {

        Food *choice = [[Food alloc] init];
        [choice placeOrder];

    }
    return 0;
}

বুঝতেই পারছেন, পুরো প্রোগ্রামটির শুরু এখান (main()) থেকেই। প্রথমে Food ক্লাস ইন্সট্যান্সিয়েট করা হচ্ছে। তারপর এর placeOrder মেথড কল করে অর্ডার সাবমিট করা হচ্ছে এবং পরবর্তীতে কুকিং শুরু, শেষ এবং Food ক্লাসকে জানিয়ে দেয়ার কাজ গুলো হচ্ছে যেসব উপর থেকে আমরা বর্ণনা করে এসেছি।

main থেকে শুরু করে Food, তারপর Make, মাঝখানে MakeProtocol এভাবে যদি আপনি নিজের মাথা দিয়ে কোড কম্পাইল করে করে উপরের দিকে আগান তাহলে আরেকবার পুরো উদাহরণটি বুঝতে উঠতে পারবেন বলে আশা করছি।

iOS অ্যাপে প্রোটোকল এর প্রয়োগঃ রিয়াল লাইফ iOS অ্যাপ্লিকেশন ডেভেলপমেন্টে প্রোটোকল এর ব্যবহার খুব সাধারণভাবেই চলে আসে। যেমনঃ "application delegate" অবজেক্ট সেরকম একটি ব্যাপার যেটি মূলত ওই অ্যাপ রান হওয়া থেকে শুরু করে যতক্ষণ চলবে ততক্ষণ বিভন্ন ইভেন্ট হ্যান্ডেল করে থাকে। রিয়াল অ্যাপ ডেভেলপ করার সময় নিচের কোড ব্লক টুকু আপনার নজরে চলে আসবে,

@interface YourAppDelegate : UIResponder <UIApplicationDelegate>

যতক্ষণ পর্যন্ত এটা (আপনার "application delegate" অবজেক্ট) UIApplicationDelegate এর মধ্যে ডিফাইন করা মেথডগুলোকে রেসপন্স করবে ততক্ষণ পর্যন্ত যেকোনো অবজেক্টকেই আপনার অ্যাপ্লিকেশন ডেলিগেট হিসেবে ব্যবহার করতে পারবেন। এতে করে অ্যাপ ইভেন্ট গুলো নিয়ে কাজ করতে সুবিধা হবে।

পরের চ্যাপ্টারঃ এই চ্যাপ্টারে আমরা প্রোটোকল নিয়ে একটি উদাহরণ এর মাধ্যমে এর ব্যবহার মোটামুটি জানতে পেরেছি। যদিও আমাদের বইয়ে আরও বিস্তারিত বিশ্লেষণ থাকবে বলে আশা করি। পরের চ্যাপ্টারে খুবি মজার এবং কাজের দুটি ফিচার অর্থাৎ অবেজক্টিভ সি এর ক্যাটাগরি (Categories) এবং ব্লক (Blocks) নিয়ে আলোচনা করা হবে।

Originally Posted Here

Last updated