Protocols এবং Delegation (প্রোটোকল এবং ডেলিগেশন)

অবজেক্টিভ-সি (Objective-C) - Computer Programming

346

Objective-C তে প্রোটোকল (Protocols) এবং ডেলিগেশন (Delegation) হল দুটি গুরুত্বপূর্ণ কনসেপ্ট যা অবজেক্ট-ওরিয়েন্টেড প্রোগ্রামিং (OOP) এর অংশ। এগুলি অ্যাপ্লিকেশন ডেভেলপমেন্টে কোডের পুনঃব্যবহারযোগ্যতা, কমপ্লেক্সিটি কমানো এবং অবজেক্টের মধ্যে যোগাযোগের সুবিধা প্রদান করে।

প্রোটোকল (Protocols)

প্রোটোকল হল একটি চুক্তি বা একটি চমৎকার উপায়, যার মাধ্যমে আপনি নির্দিষ্ট কিছু মেথডের ডিফিনিশন নির্ধারণ করতে পারেন, কিন্তু তাদের বাস্তবায়ন প্রদান করা হয় না। যখন কোনও ক্লাস একটি প্রোটোকল গ্রহণ করে, তখন সে ক্লাসটিকে ওই প্রোটোকলে থাকা সব মেথড বাস্তবায়ন (implement) করতে হবে।

প্রোটোকল ব্যবহার করার সুবিধা:

  • কোডে নির্দিষ্ট নিয়ম তৈরি করা যায়।
  • একাধিক ক্লাসের মধ্যে কাজের আদান-প্রদান সহজ হয়।
  • কোডের পুনঃব্যবহারযোগ্যতা বৃদ্ধি পায়।
প্রোটোকল ডিফাইনেশন:

Objective-C তে প্রোটোকল ডিফাইন করতে @protocol এবং @end ব্যবহার করা হয়।

@protocol CarDelegate <NSObject>
- (void) carDidStart;
- (void) carDidStop;
@end

এখানে, CarDelegate একটি প্রোটোকল যা দুটি মেথড ঘোষণা করেছে: carDidStart এবং **carDidStop**। যে ক্লাস এই প্রোটোকলটি গ্রহণ করবে, তাকে এই মেথডগুলো বাস্তবায়ন (implement) করতে হবে।

প্রোটোকল কনফর্মেন্স:

প্রোটোকলে ডিফাইন করা মেথডগুলি কোনও ক্লাসে বাস্তবায়ন করতে হলে সেই ক্লাসটি <ProtocolName> দিয়ে প্রোটোকল কনফর্ম করবে।

@interface Car : NSObject <CarDelegate>
@end

@implementation Car

- (void) carDidStart {
    NSLog(@"The car has started!");
}

- (void) carDidStop {
    NSLog(@"The car has stopped.");
}

@end

এখানে, Car ক্লাসটি CarDelegate প্রোটোকল কনফর্ম করেছে এবং এর মেথডগুলি বাস্তবায়ন করেছে।


ডেলিগেশন (Delegation)

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

ডেলিগেশন ব্যবহারের সুবিধা:

  • ক্লাসগুলোর মধ্যে সুসংগঠিত যোগাযোগ।
  • কোডের পুনঃব্যবহারযোগ্যতা।
  • এক ক্লাসে অনেক কমপ্লেক্সিটি না রেখে দায়িত্ব ভাগ করা।
ডেলিগেশন কিভাবে কাজ করে:
  • প্রথমে একটি প্রোটোকল তৈরি করা হয়, যা মেথডগুলো ধারণ করে যা ডেলিগেট ক্লাসকে বাস্তবায়ন করতে হবে।
  • ডেলিগেট ক্লাসে সেই মেথডগুলো বাস্তবায়ন করা হয়।
  • মূল ক্লাসে ডেলিগেটের একটি রেফারেন্স রাখা হয় এবং প্রয়োজনে সেই রেফারেন্সের মাধ্যমে ডেলিগেট ক্লাসের মেথড কল করা হয়।
ডেলিগেশন উদাহরণ:

ধরা যাক, আমাদের একটি Car ক্লাস রয়েছে এবং Driver ক্লাসটিকে আমরা ডেলিগেট হিসেবে ব্যবহার করতে চাই, যাতে Driver ক্লাসটি Car এর কার্যাবলি পরিচালনা করতে পারে।

CarDelegate প্রোটোকল তৈরি করা:

@protocol CarDelegate <NSObject>
- (void) carDidStart;
- (void) carDidStop;
@end

Car ক্লাসে ডেলিগেট রেফারেন্স যুক্ত করা:

@interface Car : NSObject

@property (nonatomic, weak) id<CarDelegate> delegate;

- (void) startCar;
- (void) stopCar;

@end

@implementation Car

- (void) startCar {
    NSLog(@"Car started");
    if ([self.delegate respondsToSelector:@selector(carDidStart)]) {
        [self.delegate carDidStart];  // ডেলিগেট মেথড কল করা হচ্ছে
    }
}

- (void) stopCar {
    NSLog(@"Car stopped");
    if ([self.delegate respondsToSelector:@selector(carDidStop)]) {
        [self.delegate carDidStop];  // ডেলিগেট মেথড কল করা হচ্ছে
    }
}

@end

Driver ক্লাসে ডেলিগেট প্রোটোকল গ্রহণ করা:

@interface Driver : NSObject <CarDelegate>
@end

@implementation Driver

- (void) carDidStart {
    NSLog(@"Driver: The car has started!");
}

- (void) carDidStop {
    NSLog(@"Driver: The car has stopped!");
}

@end

Car এবং Driver ক্লাসের মধ্যে যোগাযোগ:

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Car *myCar = [[Car alloc] init];
        Driver *driver = [[Driver alloc] init];
        
        myCar.delegate = driver;  // ডেলিগেট হিসেবে Driver ক্লাস সেট করা
        
        [myCar startCar];  // Driver ক্লাসের carDidStart মেথড কল হবে
        [myCar stopCar];   // Driver ক্লাসের carDidStop মেথড কল হবে
    }
    return 0;
}

এখানে, Car ক্লাসের delegate প্রপার্টি Driver ক্লাসে সেট করা হয়েছে। এরপর, যখন Car ক্লাসের startCar অথবা stopCar মেথড কল করা হয়, তখন তা Driver ক্লাসের প্রাসঙ্গিক মেথড কল করে।


সারাংশ

প্রোটোকল হল একটি চুক্তি যা ক্লাসকে কিছু নির্দিষ্ট মেথড বাস্তবায়ন করতে বাধ্য করে, যখন ডেলিগেশন হল একটি ডিজাইন প্যাটার্ন যা এক ক্লাসের কার্যক্রম অন্য ক্লাসের মাধ্যমে পরিচালিত হয়। Objective-C তে এই দুটি ধারণা একসাথে ব্যবহৃত হয়, যা কোডকে মডুলার, পুনঃব্যবহারযোগ্য এবং পরিচালনাযোগ্য করতে সাহায্য করে। ডেলিগেশন এবং প্রোটোকল ব্যবহারের মাধ্যমে কোডের মধ্যে শক্তিশালী এবং নমনীয় যোগাযোগ তৈরি করা যায়।

Content added By

অবজেক্টিভ-সি এবং সুইফট প্রোগ্রামিং ভাষায় প্রোটোকল (Protocol) একটি গুরুত্বপূর্ণ কনসেপ্ট, যা একটি চুক্তি বা কনট্রাক্ট হিসেবে কাজ করে। প্রোটোকল ব্যবহৃত হয় ক্লাস, স্ট্রাকচার বা এনাম (enum) এর মধ্যে কিছু নির্দিষ্ট মেথড বা ফাংশন ইমপ্লিমেন্ট করতে নির্দেশ দেওয়ার জন্য। এটি একটি গঠনতন্ত্র বা ইন্টারফেসের মতো কাজ করে, যা নির্দিষ্ট ফাংশনালিটি প্রয়োগের জন্য ক্লাস বা অবজেক্টকে বাধ্য করে।

প্রোটোকল ব্যবহার করে, আমরা একটি নির্দিষ্ট মেথড বা ফাংশনকে সংজ্ঞায়িত করতে পারি এবং পরে তা বিভিন্ন ক্লাসে বাস্তবায়ন করতে পারি।


১. প্রোটোকল (Protocol) এর ধারণা

প্রোটোকল একটি ধরনের চুক্তি, যা একটি ক্লাসকে বা অবজেক্টকে কিছু নির্দিষ্ট মেথড ইমপ্লিমেন্ট করতে বলে। এটি কেবল মেথডের সিগনেচার (signature) এবং বৈশিষ্ট্য সংজ্ঞায়িত করে, কিন্তু এর কার্যকরী অংশ (implementation) প্রদান করে না। যেই ক্লাস বা অবজেক্ট প্রোটোকলটি গ্রহণ করবে, সেটি সেই প্রোটোকল সংজ্ঞায়িত মেথড বা বৈশিষ্ট্যগুলি ইমপ্লিমেন্ট করবে।

প্রোটোকল ডিফিনেশন:

@protocol CarDelegate
- (void) carDidStart;
- (void) carDidStop;
@end

এখানে CarDelegate একটি প্রোটোকল যা দুটি মেথড — carDidStart এবং carDidStop — ডিফাইন করেছে। এটি কোনো নির্দিষ্ট ক্লাস বা অবজেক্টকে নির্দেশ দেয় যে তাদের এই মেথডগুলো ইমপ্লিমেন্ট করতে হবে।


২. প্রোটোকল কিভাবে কাজ করে

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

উদাহরণ:

// CarDelegate প্রোটোকল ডিফিনেশন
@protocol CarDelegate
- (void) carDidStart;
- (void) carDidStop;
@end

// Car ক্লাস যা প্রোটোকল অনুসরণ করবে
@interface Car : NSObject <CarDelegate>
- (void) startCar;
- (void) stopCar;
@end

@implementation Car
- (void) startCar {
    NSLog(@"Car started");
    [self carDidStart]; // carDidStart প্রোটোকল মেথড কল
}

- (void) stopCar {
    NSLog(@"Car stopped");
    [self carDidStop]; // carDidStop প্রোটোকল মেথড কল
}

// প্রোটোকল মেথড ইমপ্লিমেন্টেশন
- (void) carDidStart {
    NSLog(@"Car has started successfully!");
}

- (void) carDidStop {
    NSLog(@"Car has stopped successfully!");
}

@end

এখানে:

  • Car ক্লাসটি CarDelegate প্রোটোকলকে অনুসরণ করছে এবং carDidStartcarDidStop মেথডগুলো ইমপ্লিমেন্ট করছে।
  • startCar এবং stopCar মেথডগুলো carDidStart এবং carDidStop মেথডগুলো কল করে।

৩. প্রোটোকলের প্রয়োজনীয়তা

প্রোটোকল ব্যবহারের অনেক সুবিধা এবং প্রয়োজনীয়তা রয়েছে, বিশেষ করে অবজেক্ট-ওরিয়েন্টেড প্রোগ্রামিং (OOP) এর ক্ষেত্রে:

১. ইন্টারফেস ডিফিনিশন

প্রোটোকল একটি নির্দিষ্ট ইন্টারফেস সংজ্ঞায়িত করে যা বিভিন্ন ক্লাসে শেয়ার করা যেতে পারে। এটি একাধিক ক্লাসের মধ্যে সাধারণ আচরণ এবং মেথড ইমপ্লিমেন্টেশন নিশ্চিত করে।

২. ডিকাপলিং (Decoupling)

প্রোটোকল ব্যবহার করলে ক্লাসগুলো একে অপর থেকে স্বাধীন থাকে, অর্থাৎ, একটি ক্লাস অন্য ক্লাসের বাস্তবায়ন জানে না, শুধু প্রোটোকলের মেথডগুলো অনুসরণ করে। এটি কোডের নমনীয়তা এবং রক্ষণাবেক্ষণ সহজ করে।

৩. মাল্টিপল ইনহেরিট্যান্স

অবজেক্টিভ-সি তে ক্লাস একাধিক ক্লাস থেকে উত্তরাধিকারী হতে পারে না, তবে প্রোটোকল ব্যবহার করে একটি ক্লাস একাধিক প্রোটোকল গ্রহণ করতে পারে, যা মাল্টিপল ইনহেরিট্যান্স সমর্থন করে।

৪. মডুলার ডিজাইন

প্রোটোকল ব্যবহারের মাধ্যমে কোড মডুলার এবং পুনঃব্যবহারযোগ্য করা যায়। বিভিন্ন ক্লাস একই প্রোটোকল অনুসরণ করে একে অপরের সাথে সহজে ইন্টিগ্রেট হতে পারে।

৫. ডেলিগেট প্যাটার্ন (Delegate Pattern)

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

উদাহরণ: ডেলিগেট প্যাটার্ন

@protocol CarDelegate
- (void) carDidStart;
@end

@interface Car : NSObject
@property (nonatomic, weak) id<CarDelegate> delegate;
- (void) startCar;
@end

@implementation Car
- (void) startCar {
    NSLog(@"Car started");
    [self.delegate carDidStart]; // ডেলিগেট মেথড কল
}
@end

@interface Driver : NSObject <CarDelegate>
@end

@implementation Driver
- (void) carDidStart {
    NSLog(@"Driver: The car has started.");
}
@end

এখানে:

  • Car ক্লাসের একটি delegate প্রপার্টি রয়েছে যা CarDelegate প্রোটোকল অনুসরণ করে।
  • Driver ক্লাস CarDelegate প্রোটোকল গ্রহণ করে এবং carDidStart মেথডটি ইমপ্লিমেন্ট করে।

সারাংশ

  • প্রোটোকল হল একটি চুক্তি যা ক্লাস বা অবজেক্টকে কিছু নির্দিষ্ট মেথড ইমপ্লিমেন্ট করতে বলে। এটি একটি ইন্টারফেস বা কনট্রাক্ট হিসেবে কাজ করে।
  • প্রোটোকল ব্যবহারের মাধ্যমে আমরা কোডের পুনঃব্যবহারযোগ্যতা, মডুলার ডিজাইন, এবং একাধিক ক্লাসের মধ্যে সাধারণ আচরণ নিশ্চিত করতে পারি।
  • এটি ডেলিগেট প্যাটার্নের জন্য অত্যন্ত গুরুত্বপূর্ণ, যা একাধিক ক্লাসের মধ্যে কার্যক্রমের যোগাযোগ এবং সমন্বয় করতে সহায়তা করে।

প্রোটোকল ব্যবহারে কোড আরও পরিষ্কার, নির্ভরযোগ্য, এবং রক্ষণাবেক্ষণে সহজ হয়।

Content added By

Objective-C তে @protocol ডিরেক্টিভ ব্যবহার করা হয় প্রটোকল ডিফাইন করার জন্য। প্রটোকল হল একটি চুক্তি বা এক ধরনের কনট্র্যাক্ট, যা একটি ক্লাসকে নির্দিষ্ট মেথড ইমপ্লিমেন্ট করতে বলে। প্রটোকল দ্বারা আপনি একটি নির্দিষ্ট ইন্টারফেস (interface) নির্ধারণ করতে পারেন, কিন্তু এর মধ্যে মেথডের বাস্তবায়ন (implementation) করা হয় না। এটি কোডের পুনঃব্যবহারযোগ্যতা এবং মডুলারিটি বাড়াতে সাহায্য করে।

Objective-C তে প্রটোকল দুটি প্রধানভাবে ব্যবহৃত হয়:

  1. ডেলিগেট প্যাটার্ন: এক ক্লাস আরেক ক্লাসের কার্যাবলী বা অ্যাকশনগুলির উপর নজর রাখে।
  2. ডাটা শেয়ারিং: একাধিক ক্লাসে একরকম কার্যকলাপকে শেয়ার করা।

@protocol ডিরেক্টিভের সিনট্যাক্স

প্রটোকল ডিফাইন করতে @protocol ডিরেক্টিভ ব্যবহার করা হয়, এবং ক্লাস এই প্রটোকল অনুসরণ (conform) করে।

সিনট্যাক্স:

@protocol ProtocolName

// মেথড ডিক্লেয়ারেশন
- (void) methodName;

@end

এখানে:

  • ProtocolName: প্রটোকলের নাম।
  • methodName: প্রটোকল এ ডিক্লেয়ার করা মেথড।

প্রটোকল ইমপ্লিমেন্টেশন (Protocol Implementation)

একটি ক্লাস প্রটোকল অনুসরণ (conform) করলে, সেটি প্রটোকলের মেথড ইমপ্লিমেন্ট করতে বাধ্য হয়। ক্লাসে প্রটোকল ইমপ্লিমেন্ট করার জন্য, <ProtocolName> সাইন ব্যবহার করা হয়।

উদাহরণ:

  1. প্রটোকল ডিফাইন করা (protocol definition):
// MyProtocol.h
#import <Foundation/Foundation.h>

@protocol MyProtocol <NSObject>

// প্রটোকলের মেথড ডিক্লেয়ারেশন
- (void) sayHello;
- (void) greetWithName:(NSString *)name;

@end
  1. প্রটোকল ইমপ্লিমেন্টেশন (protocol implementation):
// MyClass.h
#import <Foundation/Foundation.h>
#import "MyProtocol.h"

@interface MyClass : NSObject <MyProtocol> // প্রটোকল কনফর্ম করা

// প্রপার্টি বা মেথড ডিক্লেয়ারেশন
- (void) sayHello;
- (void) greetWithName:(NSString *)name;

@end
// MyClass.m
#import "MyClass.h"

@implementation MyClass

// প্রটোকল মেথড ইমপ্লিমেন্টেশন
- (void) sayHello {
    NSLog(@"Hello!");
}

- (void) greetWithName:(NSString *)name {
    NSLog(@"Hello, %@!", name);
}

@end
  1. প্রটোকল ব্যবহার:
// main.m
#import <Foundation/Foundation.h>
#import "MyClass.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        MyClass *obj = [[MyClass alloc] init];
        [obj sayHello];  // MyProtocol এর sayHello মেথড কল হচ্ছে
        [obj greetWithName:@"John"];  // MyProtocol এর greetWithName মেথড কল হচ্ছে
    }
    return 0;
}

এখানে, MyClass ক্লাসটি MyProtocol প্রটোকল অনুসরণ (conform) করেছে এবং এর মেথডগুলি ইমপ্লিমেন্ট করেছে। sayHello এবং greetWithName: মেথড দুটি প্রটোকল থেকে এসেছে এবং ক্লাসের মধ্যে বাস্তবায়িত হয়েছে।


প্রটোকলের Optional মেথড

Objective-C তে আপনি কিছু মেথডকে optional বা ঐচ্ছিক হিসেবে চিহ্নিত করতে পারেন। এটি করার জন্য @optional ডিরেক্টিভ ব্যবহার করা হয়। প্রটোকলের কিছু মেথড ঐচ্ছিক করা হলে, ক্লাসগুলো ঐ মেথডগুলি ইমপ্লিমেন্ট নাও করতে পারে।

উদাহরণ:

@protocol MyProtocol <NSObject>

@required
- (void) requiredMethod;

@optional
- (void) optionalMethod;

@end

এখানে:

  • @required দিয়ে আপনি মেথডটি বাধ্যতামূলক করেন।
  • @optional দিয়ে আপনি মেথডটি ঐচ্ছিক করে দেন।

প্রটোকলের ডেলিগেট প্যাটার্ন

একটি সাধারণ ব্যবহারিক উদাহরণ হলো ডেলিগেট প্যাটার্ন। এতে একটি ক্লাস অন্য ক্লাসের কার্যাবলী পরিচালনা করার জন্য প্রটোকল ব্যবহার করে। উদাহরণস্বরূপ, আপনি একটি UIViewController ক্লাসে ডেলিগেট ব্যবহার করতে পারেন, যা একটি TableView এর ডেটা পরিচালনা করে।

// TableViewDelegate.h
@protocol TableViewDelegate <NSObject>
- (void) didSelectRowAtIndex:(NSInteger)index;
@end
// TableViewController.h
#import <UIKit/UIKit.h>
#import "TableViewDelegate.h"

@interface TableViewController : UIViewController

@property (nonatomic, weak) id<TableViewDelegate> delegate;

@end
// MainViewController.h
#import <UIKit/UIKit.h>
#import "TableViewDelegate.h"

@interface MainViewController : UIViewController <TableViewDelegate>

@end
// MainViewController.m
@implementation MainViewController

- (void) didSelectRowAtIndex:(NSInteger)index {
    NSLog(@"Row at index %ld selected", (long)index);
}

@end

এখানে, MainViewController TableViewDelegate প্রটোকল অনুসরণ করছে এবং didSelectRowAtIndex: মেথডটি ইমপ্লিমেন্ট করেছে। যখন TableViewController একটি রো নির্বাচন করবে, তখন এটি ডেলিগেটের মাধ্যমে MainViewController-এ পৌঁছাবে।


উপসংহার

  • @protocol ডিরেক্টিভ ব্যবহার করে আপনি একটি প্রটোকল তৈরি করতে পারেন, যা ক্লাসগুলোকে নির্দিষ্ট মেথড ইমপ্লিমেন্ট করার নির্দেশনা দেয়।
  • প্রটোকল ব্যবহারের মাধ্যমে কোডের পুনঃব্যবহারযোগ্যতা, মডুলারিটি এবং নমনীয়তা বৃদ্ধি পায়।
  • @required এবং @optional ডিরেক্টিভের মাধ্যমে আপনি মেথডগুলিকে বাধ্যতামূলক বা ঐচ্ছিক হিসেবে চিহ্নিত করতে পারেন।

এই কনসেপ্টগুলি Objective-C তে কোডকে আরও উন্নত, পরিষ্কার এবং মডুলার করে তোলে, বিশেষ করে যখন বড় অ্যাপ্লিকেশন ডেভেলপমেন্টে ডেলিগেট বা ইভেন্ট হ্যান্ডলিং প্রয়োজন হয়।

Content added By

Delegation Pattern একটি অবজেক্ট-ওরিয়েন্টেড ডিজাইন প্যাটার্ন যা এক অবজেক্টের কাজ বা দায়িত্ব অন্য অবজেক্টকে Delegate (অথবা পাঠানো) করার মাধ্যমে কাজ করে। এই প্যাটার্নটি মূলত একটি অবজেক্ট অন্য একটি অবজেক্টকে দায়িত্ব দেয় এবং সেই অবজেক্ট কাজটি সম্পাদন করে, মূল অবজেক্টের বদলে। এইভাবে, একাধিক অবজেক্টের মধ্যে কমিউনিকেশন বা যোগাযোগ স্থাপন করা সম্ভব হয়।

Delegation হল অবজেক্ট-ওরিয়েন্টেড প্রোগ্রামিং (OOP)-এর একটি মৌলিক কৌশল যা অনেক প্রোগ্রামিং ভাষায় ব্যবহৃত হয়, যেমন Objective-C, Swift, Java, এবং **C#**। এটি ব্যাপকভাবে ব্যবহৃত হয় অ্যাপ্লিকেশন ডিজাইন এবং ইভেন্ট হ্যান্ডলিং এর ক্ষেত্রে।


Delegation Pattern এর মূল ধারণা

  1. Sender (Delegator): এটি সেই অবজেক্ট যা কাজটি করতে সক্ষম নয় বা কাজটি অন্য অবজেক্টে প্রেরণ করতে চায়। এটি ডেলিগেট অবজেক্টকে অ্যাকশন বা দায়িত্ব পাঠায়।
  2. Receiver (Delegate): এটি সেই অবজেক্ট যা ডেলিগেটেড কাজটি সম্পাদন করবে। এটি কার্যক্রমের জন্য দায়ী।
  3. Protocol (Interface): ডেলিগেট অবজেক্টের সাথে যোগাযোগের জন্য একে প্রোটোকল বা ইন্টারফেসের মাধ্যমে যোগাযোগ করা হয়। এটি প্রোগ্রামের অন্যান্য অংশকে ডেলিগেট অবজেক্টের বৈশিষ্ট্য জানায়।

Delegation Pattern এর ব্যবহার উদাহরণ (Objective-C)

Objective-C-এ delegation প্যাটার্ন সাধারণত protocol ব্যবহার করে প্রয়োগ করা হয়। Sender অবজেক্ট তার কাজ Receiver (delegate) অবজেক্টের কাছে পাঠায়। প্রোটোকল (interface) অবজেক্টের মধ্যে যে মেথড বা আচরণ ডেলিগেট করা হচ্ছে তা ঘোষণা করে।

১. Sender এবং Delegate এর মধ্যে যোগাযোগ

// Delegate.h - Protocol Declaration
@protocol Delegate <NSObject>
- (void)didFinishTask;
@end

// Sender.h - Sender Class Declaration
#import <Foundation/Foundation.h>
#import "Delegate.h"

@interface Sender : NSObject
@property (nonatomic, weak) id<Delegate> delegate;
- (void)startTask;
@end

// Sender.m - Sender Class Implementation
#import "Sender.h"

@implementation Sender

- (void)startTask {
    // Task is started and completed
    NSLog(@"Task started!");
    
    // Notify delegate once task is finished
    [self.delegate didFinishTask];
}

@end

// Receiver.h - Receiver Class Declaration
#import <Foundation/Foundation.h>
#import "Delegate.h"

@interface Receiver : NSObject <Delegate>
- (void)didFinishTask;
@end

// Receiver.m - Receiver Class Implementation
#import "Receiver.h"

@implementation Receiver

- (void)didFinishTask {
    // Handle the task completion
    NSLog(@"Task completed by the delegate.");
}

@end

// Main.m - Usage Example
#import <Foundation/Foundation.h>
#import "Sender.h"
#import "Receiver.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Sender *sender = [[Sender alloc] init];
        Receiver *receiver = [[Receiver alloc] init];
        
        // Setting the delegate
        sender.delegate = receiver;
        
        // Start the task
        [sender startTask];
    }
    return 0;
}

ব্যাখ্যা:

  1. Delegate Protocol: প্রথমে Delegate নামে একটি প্রোটোকল ডিফাইন করা হয়েছে, যা একটি মেথড didFinishTask ঘোষণা করছে।
  2. Sender Class: Sender ক্লাসে একটি প্রপার্টি delegate রয়েছে যা Delegate প্রোটোকলকে সম্মত একটি অবজেক্টকে রেফার করে। startTask মেথডটি কাজ শুরু করার পরে ডেলিগেটকে অবহিত করার জন্য didFinishTask মেথড কল করে।
  3. Receiver Class: Receiver ক্লাসটি Delegate প্রোটোকল গ্রহণ করে এবং didFinishTask মেথডে কাজ করার সময় প্রয়োজনীয় ব্যবস্থা নেয়।
  4. Main: Sender অবজেক্টের delegate প্রপার্টি Receiver অবজেক্টে সেট করা হয়, এবং startTask মেথডটি কল করা হয়, যা ডেলিগেট অবজেক্টে যোগাযোগ করে।

আউটপুট:

Task started!
Task completed by the delegate.

Delegation Pattern এর সুবিধা

  1. Separation of Concerns: এটি কোডের ভিন্ন ভিন্ন অংশের মধ্যে দায়িত্ব ভাগ করে দেয়, ফলে একটি ক্লাস বা অবজেক্ট একাধিক দায়িত্ব না নিয়ে একটি নির্দিষ্ট কাজের জন্য মনোনিবেশ করতে পারে।
  2. Reuse: ডেলিগেশন প্যাটার্ন অবজেক্টের আচরণ পুনঃব্যবহারযোগ্য করে তোলে। এক ক্লাস একটি নির্দিষ্ট কাজের জন্য ডেলিগেট হতে পারে, এবং সেই কাজ অন্য ক্লাস দ্বারা পুনরায় ব্যবহৃত হতে পারে।
  3. Low Coupling: এক অবজেক্ট তার কাজ অন্য অবজেক্টকে ডেলিগেট করার মাধ্যমে, কোডের মধ্যে লো কপলিং (Low Coupling) স্থাপন হয়, অর্থাৎ দুইটি অবজেক্টের মধ্যে শক্তিশালী সম্পর্ক তৈরি হয় না, যা কোডে পরিবর্তন এবং রক্ষণাবেক্ষণ সহজ করে।

Delegation Pattern এর প্রকার

  1. One-to-One Delegation: এটি সবচেয়ে সাধারণ প্যাটার্ন, যেখানে একটি অবজেক্ট তার কাজ একটি একক ডেলিগেট অবজেক্টে পাঠায়। উপরের উদাহরণটি এর একটি চমৎকার উদাহরণ।
  2. One-to-Many Delegation: একাধিক ডেলিগেটকে একত্রে কাজ দেওয়া। এখানে এক ডেলিগেটের পরিবর্তে একাধিক অবজেক্ট কাজটি সম্পন্ন করবে। সাধারণত অ্যাপ্লিকেশনের ইভেন্ট হ্যান্ডলিং ব্যবস্থায় এই প্যাটার্ন ব্যবহার করা হয়।

Delegation Pattern এর অন্যান্য উদাহরণ

  1. UITableViewDelegate: UITableView বা UICollectionView এর মাধ্যমে ব্যবহৃত হয় যেখানে ভিউ (View) অবজেক্টের কিছু কার্যকলাপ (যেমন সেল নির্বাচন) ডেলিগেট করা হয়। UITableViewDelegate প্রোটোকলটি কল করা হয়।
  2. UIControlEvent: UIButton বা অন্যান্য কন্ট্রোল উপাদানের ইভেন্ট হ্যান্ডলিংয়ের জন্য ডেলিগেশন ব্যবহৃত হয়। উদাহরণস্বরূপ, একটি বাটনে ট্যাপ করার পরে ডেলিগেট মেথড কল করা হয়।

সারাংশ

  • Delegation Pattern হলো একটি ডিজাইন প্যাটার্ন যা এক অবজেক্টের কাজ অন্য অবজেক্টে ডেলিগেট করার মাধ্যমে বাস্তবায়িত হয়।
  • এটি Separation of Concerns এবং Low Coupling নিশ্চিত করে, ফলে কোড ব্যবস্থাপনা সহজ হয়।
  • Objective-C এবং Swift ভাষায় এই প্যাটার্ন ব্যাপকভাবে ব্যবহৃত হয়, যেমন UITableViewDelegate, UIControlEvent, ইত্যাদি ক্ষেত্রে।
  • এটি অনেক ইভেন্ট-ভিত্তিক এবং UI প্রোগ্রামিং ডিজাইনে খুবই গুরুত্বপূর্ণ ভূমিকা পালন করে।

Delegation প্যাটার্নের মাধ্যমে অবজেক্টগুলির মধ্যে যোগাযোগ স্থাপন এবং কার্যকলাপ ভাগ করে নেওয়া যায়, যা কোডের কার্যক্ষমতা এবং পুনঃব্যবহারযোগ্যতা উন্নত করে।

Content added By

Objective-C তে Optional এবং Required মেথড দুটি গুরুত্বপূর্ণ ধারণা, যা প্রোটোকল (protocol) এর সাথে সম্পর্কিত। প্রোটোকল একটি চুক্তি, যা ক্লাসকে কিছু নির্দিষ্ট মেথড বা প্রপার্টি ইমপ্লিমেন্ট করতে বলে। এখানে Optional এবং Required মেথডের মধ্যে পার্থক্য কী তা বিস্তারিতভাবে ব্যাখ্যা করা হয়েছে।


১. Required Methods

Required methods হল এমন মেথড যেগুলি একটি প্রোটোকল অনুসরণকারী ক্লাসকে অবশ্যই ইমপ্লিমেন্ট করতে হবে। যদি একটি ক্লাস একটি প্রোটোকল কনফর্ম করে, তবে সেই ক্লাসকে প্রোটোকলে ডিফাইন করা Required methods গুলি অবশ্যই ইমপ্লিমেন্ট করতে হবে। Required methods ক্লাসের জন্য বাধ্যতামূলক এবং এটি ক্লাসের কাজের জন্য অপরিহার্য।

উদাহরণ:

#import <Foundation/Foundation.h>

@protocol AnimalDelegate <NSObject>
@required  // Required মেথড
- (void) makeSound;
@end

@interface Dog : NSObject <AnimalDelegate>
@end

@implementation Dog
- (void) makeSound {
    NSLog(@"Bark");
}
@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Dog *myDog = [[Dog alloc] init];
        [myDog makeSound];  // Required মেথডটি ইমপ্লিমেন্ট করা হয়েছে
    }
    return 0;
}

বিশেষ দৃষ্টি:

  • @required: এটি প্রোটোকলে ডিফাইন করা মেথডকে বাধ্যতামূলক করে তোলে।
  • ক্লাস DogmakeSound মেথডটি প্রোটোকল অনুসরণ করার জন্য ইমপ্লিমেন্ট করতে হয়েছে।

২. Optional Methods

Optional methods হল এমন মেথড যেগুলি একটি প্রোটোকল অনুসরণকারী ক্লাসকে ইচ্ছামত ইমপ্লিমেন্ট করতে হয়। এটি শুধুমাত্র একটি বিকল্প, এবং ক্লাসের জন্য এগুলি ইমপ্লিমেন্ট করা বাধ্যতামূলক নয়। যদি একটি ক্লাস একটি প্রোটোকলের Optional মেথড ইমপ্লিমেন্ট না করে, তবে তাও কোনও সমস্যা নেই এবং এটি সঠিকভাবে কাজ করবে।

উদাহরণ:

#import <Foundation/Foundation.h>

@protocol AnimalDelegate <NSObject>
@optional  // Optional মেথড
- (void) sleep;
@end

@interface Cat : NSObject <AnimalDelegate>
@end

@implementation Cat
- (void) sleep {
    NSLog(@"The cat is sleeping");
}
@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Cat *myCat = [[Cat alloc] init];
        [myCat sleep];  // Optional মেথডটি ইমপ্লিমেন্ট করা হয়েছে
    }
    return 0;
}

বিশেষ দৃষ্টি:

  • @optional: এটি প্রোটোকলে ডিফাইন করা মেথডকে ঐচ্ছিক করে তোলে, অর্থাৎ ক্লাসের পক্ষে তা ইমপ্লিমেন্ট না করলেও চলবে।
  • ক্লাস Catsleep মেথডটি Optional হওয়ায় এটি শুধুমাত্র ইচ্ছামত ইমপ্লিমেন্ট করা হয়েছে।

Optional এবং Required Methods এর মধ্যে পার্থক্য

বৈশিষ্ট্যRequired MethodsOptional Methods
বাধ্যতামূলকহ্যাঁ, ক্লাসকে ইমপ্লিমেন্ট করতে হয়না, ক্লাস ইচ্ছামত ইমপ্লিমেন্ট করতে পারে
@required বা @optional নির্দেশক@required ব্যবহার করা হয়@optional ব্যবহার করা হয়
প্রোটোকল ফলো করার জন্য ক্লাসের দায়িত্বRequired মেথড ইমপ্লিমেন্ট করা বাধ্যতামূলকOptional মেথড ইমপ্লিমেন্ট করা ঐচ্ছিক
ক্লাসের কাজের জন্য অপরিহার্যতাএটি ক্লাসের কাজের জন্য অপরিহার্যএটি ঐচ্ছিক এবং ক্লাসের কার্যকারিতার জন্য অপরিহার্য নয়

সারাংশ

  • Required methods: প্রোটোকলে ডিফাইন করা মেথড গুলি একটি ক্লাসকে অবশ্যই ইমপ্লিমেন্ট করতে হয়, এটি ক্লাসের কাজের জন্য অপরিহার্য।
  • Optional methods: প্রোটোকলে ডিফাইন করা মেথড গুলি ইচ্ছামত ইমপ্লিমেন্ট করা হয়, এবং এটি ক্লাসের কাজের জন্য অপরিহার্য নয়।

Objective-C তে এই দুটি বৈশিষ্ট্য প্রোটোকলের মাধ্যমে ক্লাসের আচরণ কাস্টমাইজ করতে সাহায্য করে এবং কোডের নমনীয়তা বৃদ্ধি করে।

Content added By
Promotion

Are you sure to start over?

Loading...