প্রটোকল (Protocol) এবং ডেলিগেশন (Delegation) Swift-এ কোড ম্যানেজমেন্ট এবং পুনঃব্যবহারযোগ্যতা বাড়াতে ব্যবহৃত গুরুত্বপূর্ণ কনসেপ্ট।
Swift- এ প্রটোকল (Protocol)
প্রটোকল হলো একটি ব্লুপ্রিন্ট যা মেথড, প্রপার্টি, এবং অন্যান্য প্রয়োজনীয় ফাংশনালিটি নির্ধারণ করে। এটি একটি ইন্টারফেসের মতো, যা নিশ্চিত করে যে প্রোটোকল গ্রহণ করা (adopt) ক্লাস বা স্ট্রাকচারগুলি নির্দিষ্ট ফাংশনালিটি ইমপ্লিমেন্ট করবে।
প্রটোকল ডিক্লেয়ারেশন উদাহরণ:
protocol Drivable {
func drive()
}
Swift- এ ডেলিগেশন (Delegation)
ডেলিগেশন হলো একটি ডিজাইন প্যাটার্ন যা প্রটোকল ব্যবহার করে কাজ করে। এটি এক অবজেক্টের কাজ অন্য অবজেক্টে পাঠিয়ে দেয়, ফলে কোডকে সহজ, মডুলার এবং পুনঃব্যবহারযোগ্য করে।
ডেলিগেশন উদাহরণ:
protocol TaskDelegate {
func taskDidComplete()
}
class Worker {
var delegate: TaskDelegate?
func doWork() {
// কাজ শেষ হলে ডেলিগেটকে জানানো হচ্ছে
delegate?.taskDidComplete()
}
}
class Manager: TaskDelegate {
func taskDidComplete() {
print("Task completed!")
}
}
let worker = Worker()
let manager = Manager()
worker.delegate = manager
worker.doWork() // আউটপুট: "Task completed!"
প্রটোকল এবং ডেলিগেশনের সুবিধা
- কোড পুনঃব্যবহারযোগ্যতা: ডেলিগেশন ব্যবহার করে কাজ ভাগ করা সহজ হয়।
- ডিকাপলিং: অবজেক্টগুলোকে পরস্পরের উপর নির্ভরশীল না করে মডুলার করা যায়।
- ফ্লেক্সিবিলিটি: প্রটোকল ব্যবহার করে ক্লাস বা স্ট্রাকচারকে সহজে নতুন ফাংশনালিটি যোগ বা পরিবর্তন করা যায়।
সংক্ষেপে
Swift-এ প্রটোকল এবং ডেলিগেশন ব্যবহার করে কোডকে আরও মডুলার, পুনঃব্যবহারযোগ্য, এবং সংগঠিত করা যায়। এটি কোড ম্যানেজমেন্ট এবং ফ্লেক্সিবিলিটির জন্য অত্যন্ত কার্যকরী।
Swift-এ প্রটোকল হলো একটি ব্লুপ্রিন্ট বা টেমপ্লেট, যা একটি বা একাধিক প্রোপার্টি, মেথড, এবং অন্যান্য প্রয়োজনীয়তাগুলির ডিফিনিশন ধারণ করে। প্রটোকল আসলে কোনো নির্দিষ্ট বাস্তবায়ন (implementation) প্রদান করে না, বরং নির্দেশ করে কীভাবে একটি ক্লাস, স্ট্রাক্ট, বা এনামকে সেই প্রটোকল মেনে কাজ করতে হবে। প্রটোকল ব্যবহার করে আমরা কোডকে আরও মডুলার, পুনঃব্যবহারযোগ্য, এবং ফ্লেক্সিবল করতে পারি।
প্রটোকল কীভাবে কাজ করে?
প্রটোকল তৈরি করতে protocol কীওয়ার্ড ব্যবহার করা হয়। প্রটোকলের মধ্যে ডিফাইন করা মেথড বা প্রোপার্টির জন্য কোনো বডি (কোড) সরবরাহ করা হয় না; এটি শুধুমাত্র তাদের সিগনেচার নির্ধারণ করে।
প্রটোকলের গঠন
protocol ProtocolName {
// প্রোপার্টি
var someProperty: Type { get set }
// মেথড
func someMethod(param: Type) -> ReturnType
}
protocol: প্রটোকল ডিফাইন করার জন্য কীওয়ার্ড।- প্রোপার্টি: প্রোটোকলে ডিফাইন করা প্রোপার্টির গেটার এবং সেটার থাকতে পারে (বা শুধু গেটার থাকতে পারে)।
- মেথড: প্রোটোকলে ডিফাইন করা মেথডের শুধু সিগনেচার থাকে, কোনো বাস্তবায়ন থাকে না।
প্রটোকল উদাহরণ
protocol Describable {
var description: String { get }
func describe() -> String
}
- এখানে,
Describableনামের একটি প্রটোকল ডিফাইন করা হয়েছে, যা একটি প্রোপার্টি (description) এবং একটি মেথড (describe()) ধারণ করে। - প্রোপার্টিটি শুধু গেটার রয়েছে, আর মেথডটি কোনো প্যারামিটার নেয় না এবং একটি
Stringরিটার্ন করে।
প্রটোকল গ্রহণ করা (Conforming to Protocol)
কোনো ক্লাস, স্ট্রাক্ট, বা এনাম প্রটোকল গ্রহণ করতে চাইলে : ProtocolName ব্যবহার করতে হয়। প্রটোকল গ্রহণ করার পরে, সেই ক্লাস, স্ট্রাক্ট, বা এনামকে প্রটোকলে উল্লেখিত সব প্রোপার্টি ও মেথড বাস্তবায়ন করতে হয়।
struct Car: Describable {
var brand: String
var model: String
var description: String {
return "\(brand) \(model)"
}
func describe() -> String {
return "This is a \(brand) model \(model)."
}
}
let myCar = Car(brand: "Tesla", model: "Model S")
print(myCar.description) // Output: "Tesla Model S"
print(myCar.describe()) // Output: "This is a Tesla model Model S."
- এখানে,
Carস্ট্রাক্টDescribableপ্রটোকল গ্রহণ করেছে এবং প্রটোকলে উল্লেখিত প্রোপার্টি ও মেথড বাস্তবায়ন করেছে।
প্রটোকল ইনহেরিটেন্স
Swift-এ প্রটোকল ইনহেরিট করা যায়, যেমন ক্লাসের ক্ষেত্রে হয়। একটি প্রটোকল অন্য প্রটোকল ইনহেরিট করতে পারে এবং সেই প্রটোকলের প্রোপার্টি ও মেথডগুলিও অ্যাডাপ্ট করতে হবে।
protocol Vehicle {
var speed: Int { get set }
func start()
}
protocol ElectricVehicle: Vehicle {
var batteryLevel: Int { get set }
func charge()
}
struct ElectricCar: ElectricVehicle {
var speed: Int
var batteryLevel: Int
func start() {
print("Car started.")
}
func charge() {
print("Car is charging.")
}
}
let myElectricCar = ElectricCar(speed: 100, batteryLevel: 80)
myElectricCar.start() // Output: "Car started."
myElectricCar.charge() // Output: "Car is charging."
- এখানে,
ElectricVehicleপ্রটোকলVehicleপ্রটোকল ইনহেরিট করেছে।ElectricCarস্ট্রাক্টটিElectricVehicleপ্রটোকল গ্রহণ করেছে এবং সব প্রোপার্টি ও মেথড বাস্তবায়ন করেছে।
প্রটোকল কম্পোজিশন
Swift-এ আমরা একাধিক প্রটোকল একসাথে গ্রহণ করতে পারি। এটিকে প্রটোকল কম্পোজিশন বলা হয়।
protocol Drivable {
func drive()
}
protocol Flyable {
func fly()
}
struct FlyingCar: Drivable, Flyable {
func drive() {
print("Driving on the road.")
}
func fly() {
print("Flying in the sky.")
}
}
let myFlyingCar = FlyingCar()
myFlyingCar.drive() // Output: "Driving on the road."
myFlyingCar.fly() // Output: "Flying in the sky."
- এখানে,
FlyingCarস্ট্রাক্ট দুটি প্রটোকল (DrivableএবংFlyable) গ্রহণ করেছে এবং তাদের মেথড বাস্তবায়ন করেছে।
প্রটোকল ব্যবহার: ডেলিগেট প্যাটার্ন
Swift-এ প্রটোকল প্রায়শই ডেলিগেট প্যাটার্ন হিসেবে ব্যবহৃত হয়, যেখানে একটি অবজেক্ট তার কার্যক্রম অন্য একটি অবজেক্টে ডেলিগেট করতে পারে। এটি কোডকে আরও মডুলার এবং ডিকাপল করা (কম পরস্পর নির্ভরশীল) করতে সাহায্য করে।
ডেলিগেট প্যাটার্নের উদাহরণ
protocol DownloadDelegate {
func downloadDidStart()
func downloadDidFinish()
}
class FileDownloader {
var delegate: DownloadDelegate?
func startDownload() {
delegate?.downloadDidStart()
print("Downloading...")
delegate?.downloadDidFinish()
}
}
class DownloadHandler: DownloadDelegate {
func downloadDidStart() {
print("Download started.")
}
func downloadDidFinish() {
print("Download finished.")
}
}
let downloader = FileDownloader()
let handler = DownloadHandler()
downloader.delegate = handler
downloader.startDownload()
// Output:
// "Download started."
// "Downloading..."
// "Download finished."
- এখানে,
DownloadDelegateএকটি প্রটোকল, যা দুটি মেথড ডিফাইন করে। FileDownloaderক্লাসে একটি ডেলিগেট প্রোপার্টি রয়েছে, যাDownloadDelegateপ্রটোকল গ্রহণ করে।DownloadHandlerক্লাসটিDownloadDelegateপ্রটোকল গ্রহণ করে এবং মেথডগুলির বাস্তবায়ন করে।
প্রটোকল এক্সটেনশন
Swift-এ প্রটোকল এক্সটেনশনের মাধ্যমে আমরা প্রটোকলে ডিফল্ট বাস্তবায়ন প্রদান করতে পারি। এটি কোডকে আরও ফ্লেক্সিবল করে এবং প্রোটোকল গ্রহণকারী ক্লাস বা স্ট্রাক্টকে সব সময় মেথড বাস্তবায়ন করতে হয় না।
protocol Identifiable {
var id: String { get }
func identify()
}
extension Identifiable {
func identify() {
print("My ID is \(id).")
}
}
struct User: Identifiable {
var id: String
}
let user = User(id: "12345")
user.identify() // Output: "My ID is 12345."
- এখানে,
Identifiableপ্রটোকলে একটি ডিফল্ট বাস্তবায়ন প্রদান করা হয়েছেidentify()মেথডের জন্য। তাইUserস্ট্রাক্টে এই মেথড পুনরায় বাস্তবায়ন করতে হয়নি।
উপসংহার
Swift-এ প্রটোকল হলো একটি শক্তিশালী টুল, যা প্রোগ্রামিংয়ের ক্ষেত্রে ডেটা টাইপ এবং আচরণ নির্ধারণ করতে সাহায্য করে।
- প্রটোকল ব্যবহার করে কোডকে আরও মডুলার এবং পুনঃব্যবহারযোগ্য করা যায়।
- প্রটোকল কম্পোজিশন, ইনহেরিটেন্স, এবং এক্সটেনশন ব্যবহার করে প্রোগ্রামে ফ্লেক্সিবল এবং ডাইনামিক কাজ করা যায়।
- ডেলিগেট প্যাটার্নের মাধ্যমে প্রটোকল ব্যবহার করে কোডকে ডিকাপল এবং মডুলার করা যায়।
Swift-এ প্রটোকলের ব্যবহার প্রোগ্রামের স্থায়িত্ব, পুনঃব্যবহারযোগ্যতা, এবং মডিউলারিটি বাড়িয়ে তোলে।
ডেলিগেশন প্যাটার্ন হলো Swift বা অন্যান্য অবজেক্ট-ওরিয়েন্টেড প্রোগ্রামিং ভাষায় একটি গুরুত্বপূর্ণ এবং বহুল ব্যবহৃত ডিজাইন প্যাটার্ন, যা একটি অবজেক্ট তার দায়িত্ব বা কার্যক্রম আরেকটি অবজেক্টের কাছে অর্পণ করতে ব্যবহার করে। এটি কোডকে আরও মডুলার, পুনঃব্যবহারযোগ্য এবং মেইনটেইনেবল করে তোলে।
Swift-এ ডেলিগেশন প্যাটার্ন
Swift-এ ডেলিগেশন সাধারণত প্রোটোকল (protocol) এবং ক্লাস বা স্ট্রাক্ট ব্যবহার করে ইমপ্লিমেন্ট করা হয়। একটি অবজেক্ট (ডেলিগেটর) ডেলিগেট প্রোটোকলের মাধ্যমে তার কিছু কাজ ডেলিগেট (অন্য অবজেক্ট) এর কাছে অর্পণ করে।
ডেলিগেশন প্যাটার্নের উপাদান
১. প্রোটোকল (Protocol): এটি ডেলিগেটর ক্লাস বা স্ট্রাক্টের জন্য একটি রুল বা নির্দেশিকা তৈরি করে, যা ডেলিগেট ক্লাস বা স্ট্রাক্টকে অনুসরণ করতে হয়। ২. ডেলিগেটর (Delegator): এটি মূল ক্লাস বা অবজেক্ট, যেটি তার কিছু কাজ ডেলিগেটের কাছে পাঠায়। ৩. ডেলিগেট (Delegate): এটি সেই ক্লাস বা অবজেক্ট, যা ডেলিগেটর থেকে কাজ গ্রহণ করে এবং প্রোটোকল অনুযায়ী কাজ সম্পন্ন করে।
ডেলিগেশন প্যাটার্নের উদাহরণ
আমরা একটি সাধারণ উদাহরণ ব্যবহার করবো যেখানে একটি ক্লাস Teacher শিক্ষার্থীকে (অন্য ক্লাস) একটি কাজ ডেলিগেট করছে। শিক্ষার্থীরা বিভিন্ন কাজ করে এবং তাদের কাজের ফলাফল প্রদর্শন করে।
ধাপ ১: প্রোটোকল তৈরি করা
প্রথমে আমরা একটি প্রোটোকল তৈরি করবো, যা ডেলিগেটর (Teacher) ব্যবহার করবে এবং ডেলিগেট (Student) অনুসরণ করবে।
protocol HomeworkDelegate: AnyObject {
func completeAssignment(topic: String)
}
এখানে, HomeworkDelegate প্রোটোকলটি একটি মেথড ডিফাইন করছে completeAssignment(topic:), যা ডেলিগেটর ডেলিগেটকে কল করবে।
ধাপ ২: ডেলিগেটর ক্লাস তৈরি করা
এরপর আমরা Teacher ক্লাস তৈরি করবো, যা এই প্রোটোকল ব্যবহার করবে এবং ডেলিগেটকে কাজ অর্পণ করবে।
class Teacher {
weak var delegate: HomeworkDelegate? // ডেলিগেট প্রপার্টি
func assignHomework(topic: String) {
print("Teacher assigned homework on: \(topic)")
delegate?.completeAssignment(topic: topic)
}
}
এখানে, Teacher ক্লাসে একটি delegate প্রপার্টি আছে, যা HomeworkDelegate প্রোটোকল অনুসরণকারী কোনো অবজেক্টকে রেফারেন্স করে। assignHomework মেথডে ডেলিগেটকে কল করা হচ্ছে যাতে ডেলিগেট কাজটি সম্পন্ন করতে পারে।
ধাপ ৩: ডেলিগেট ক্লাস তৈরি করা
এরপর আমরা Student ক্লাস তৈরি করবো, যা HomeworkDelegate প্রোটোকল অনুসরণ করবে এবং কাজ সম্পন্ন করবে।
class Student: HomeworkDelegate {
var name: String
init(name: String) {
self.name = name
}
func completeAssignment(topic: String) {
print("\(name) completed the assignment on: \(topic)")
}
}
এখানে, Student ক্লাস HomeworkDelegate প্রোটোকল অনুসরণ করছে এবং completeAssignment মেথড ইমপ্লিমেন্ট করছে।
ধাপ ৪: ডেলিগেশন সেটআপ এবং কাজ সম্পাদন করা
এখন আমরা Teacher এবং Student এর অবজেক্ট তৈরি করবো এবং ডেলিগেট প্যাটার্ন ইমপ্লিমেন্ট করবো।
let teacher = Teacher()
let student = Student(name: "Alice")
teacher.delegate = student // ডেলিগেট সেট করা
teacher.assignHomework(topic: "Mathematics")
আউটপুট:
Teacher assigned homework on: Mathematics
Alice completed the assignment on: Mathematics
এখানে, Teacher তার delegate প্রপার্টি হিসেবে student অবজেক্ট সেট করেছে। এরপর, assignHomework কল করার সময় Teacher ডেলিগেটকে কল করেছে, এবং Student ক্লাসের completeAssignment মেথডটি কাজ সম্পন্ন করেছে।
কেন ডেলিগেশন প্যাটার্ন ব্যবহার করা হয়?
১. কোডকে মডুলার এবং পুনঃব্যবহারযোগ্য করা: ডেলিগেশন প্যাটার্ন ব্যবহার করে কোডকে সহজে আলাদা এবং পুনঃব্যবহারযোগ্য করা যায়। ২. ক্লাসগুলির মধ্যে যোগাযোগ সহজ করা: দুটি ক্লাস একে অপরের সাথে সরাসরি যুক্ত না থেকে প্রোটোকল ব্যবহার করে ইন্টারঅ্যাক্ট করতে পারে। ৩. লুজ কাপলিং (Loose Coupling): ডেলিগেট এবং ডেলিগেটর একে অপরের উপর খুব বেশি নির্ভরশীল নয়, যার ফলে এক ক্লাস পরিবর্তন করলে অন্য ক্লাসে কম প্রভাব পড়ে।
উপসংহার
Swift-এ ডেলিগেশন প্যাটার্ন:
- একটি সাধারণ ডিজাইন প্যাটার্ন, যা কাজ অর্পণ করতে ব্যবহৃত হয়।
- প্রোটোকল এবং ডেলিগেট ব্যবহার করে এটি ক্লাসগুলির মধ্যে যোগাযোগ করে এবং কোডকে আরও মডুলার এবং মেইনটেইনেবল করে তোলে।
- অ্যাপল এর UIKit-এ বিভিন্ন ক্ষেত্রে ডেলিগেশন প্যাটার্ন ব্যবহার করা হয়, যেমন
UITableViewDelegate,UICollectionViewDelegateইত্যাদি।
Swift প্রোগ্রামিংয়ে ডেলিগেশন প্যাটার্ন একটি অত্যন্ত গুরুত্বপূর্ণ ধারণা, যা অ্যাপ্লিকেশনকে আরও রেসপন্সিভ, পুনঃব্যবহারযোগ্য এবং কার্যকর করে তোলে।
Swift-এ প্রটোকল এবং এক্সটেনশন দুটি শক্তিশালী কনসেপ্ট যা মিলে কোডকে আরও মডুলার এবং পুনঃব্যবহারযোগ্য করে তোলে।
Swift-এ প্রটোকল এবং এক্সটেনশন
প্রটোকল (Protocol)
প্রটোকল হলো একটি ব্লুপ্রিন্ট বা ইন্টারফেস যা মেথড, প্রপার্টি, এবং ফাংশনের জন্য নির্দেশনা প্রদান করে। প্রটোকল অ্যাডপ্ট করা ক্লাস, স্ট্রাকচার, বা এনামগুলিকে প্রটোকলে নির্ধারিত সমস্ত মেথড ও প্রপার্টি ইমপ্লিমেন্ট করতে হয়।
প্রটোকল উদাহরণ:
protocol Drivable {
var speed: Int { get set }
func drive()
}
এক্সটেনশন (Extension)
এক্সটেনশন Swift-এর একটি বৈশিষ্ট্য যা ক্লাস, স্ট্রাকচার, এনাম বা প্রটোকলে নতুন মেথড, প্রপার্টি, বা ফাংশন যোগ করতে ব্যবহৃত হয়, যদিও এর মূল সোর্স কোড অ্যাক্সেস না থাকলেও। এটি একটি টাইপে অতিরিক্ত ফাংশনালিটি যোগ করতে সহায়ক।
এক্সটেনশন উদাহরণ:
extension Drivable {
func startEngine() {
print("Engine started")
}
}
প্রটোকল ও এক্সটেনশনের সমন্বয়
Swift-এ প্রটোকল এবং এক্সটেনশন একত্রে ব্যবহার করে কোডের পুনঃব্যবহারযোগ্যতা বাড়ানো যায়। প্রটোকল ডিফাইন করে আপনি একটি ব্লুপ্রিন্ট তৈরি করতে পারেন, এবং এক্সটেনশন ব্যবহার করে সেই ব্লুপ্রিন্টে ডিফল্ট ইমপ্লিমেন্টেশন যোগ করতে পারেন।
প্রটোকল এবং এক্সটেনশনের উদাহরণ:
protocol Greetable {
func greet()
}
extension Greetable {
func greet() {
print("Hello!")
}
}
struct Person: Greetable {}
let person = Person()
person.greet() // আউটপুট: "Hello!"
- এখানে,
Greetableপ্রটোকলটি একটি মেথড সংজ্ঞায়িত করে এবং এক্সটেনশনে সেটির ডিফল্ট ইমপ্লিমেন্টেশন প্রদান করা হয়েছে।Personস্ট্রাকচারটি প্রটোকলটি অ্যাডপ্ট করেছে এবং তাই এক্সটেনশনে দেয়া মেথডটি ডিরেক্টলি ব্যবহার করতে পারছে।
প্রটোকল ও এক্সটেনশনের সুবিধা
- ডিফল্ট ইমপ্লিমেন্টেশন: প্রটোকলে এক্সটেনশনের মাধ্যমে ডিফল্ট ইমপ্লিমেন্টেশন যোগ করা যায়।
- কোড পুনঃব্যবহারযোগ্যতা: এক্সটেনশন ব্যবহার করে প্রটোকল অ্যাডপ্ট করা একাধিক টাইপে একই ফাংশনালিটি যুক্ত করা যায়।
- কোডের মডুলারিটি: প্রটোকল এবং এক্সটেনশন ব্যবহার করে কোডকে ছোট ছোট মডিউলে ভাগ করা সহজ হয়।
সংক্ষেপে
Swift-এ প্রটোকল এবং এক্সটেনশন একসঙ্গে ব্যবহার করে কোডের পুনঃব্যবহারযোগ্যতা এবং মডুলারিটি বাড়ানো যায়, যা কোড লেখার সময় কার্যকরী ও সুগঠিত করে।
Read more