আপডেট:
রিফাত ভাইয়ের সাজেশন অনুসারে দুটো জিনিস যোগ করলাম –
# namespace এর ব্যবহার
# instanceof ব্যাবহার করে নিশ্চিত হওয়া যে রিকোয়েস্ট করা ক্লাস আসলে মিডিয়া ইন্টারফেইস ইম্প্লিমেন্ট করে ।
এমরান ভাইয়ের পরামর্শ অনুসারে ডিজাইন বাই কন্ট্র্যাক্ট এর রেফারেন্স যোগ করলাম ।
ফ্যাক্টরি মেথড প্যাটার্ন এর কাজ তার নাম থেকেই সহজে অনুমান করা যায় । এই প্যাটার্নে একটি ফ্যাক্টরি অবজেক্ট এ একটি মেথড থাকে যার কাজ হচ্ছে আমাদের প্রয়োজনমত অবজেক্ট তৈরি করে দেওয়া । এই অবজেক্টগুলো সাধারণত একই ধরণের হয়ে থাকে । উদাহরণ হিসেবে আমরা ভাবতে পারি একটি কন্টেন্ট ম্যানেজমেন্ট সলিউশন এর কথা (যেমন: ওয়ার্ডপ্রেস, জুমলা কিংবা দ্রুপাল) যেখানে নানা ধরণের কন্টেন্ট থাকে । থাকতে পারে অডিও, ভিডিও কিংবা ফটো । এগুলোকে এক সাথে আমরা মিডিয়া হিসেবে চিন্তা করতে পারি । আবার দেখুন, এই মিডিয়াগুলোর কিছু সাধারণ বৈশিষ্ট্য থাকতে পারে, যেমন: সব মিডিয়ারই একটি পাবলিক URL থাকে, সার্ভারে লোকেশন বোঝানোর জন্য ফাইল পাথ থাকে, মিডিয়ার ফাইল সাইজ থাকে, সেই সাথে থাকে কোনটি কোন টাইপের মিডিয়া । এরকম ক্ষেত্রে আমরা একটি মিডিয়া ইন্টারফেইস তৈরি করে নিবো এবং আমাদের স্বতন্ত্র মিডিয়াগুলো এই ইন্টারফেইস ইম্প্লিমেন্ট করবে । ইন্টারফেইস ব্যবহার করে আমরা অবজেক্টগুলোর সাধারণ আচরণ নির্দিষ্ট করে দিতে পারি । যেমন আমরা সব গুলো অবজেক্টকে বাধ্য করতে পারি একটি getType() মেথড ইম্প্লিমেন্ট করতে যেটা আমাদের বলে দিবে ঐ অবজেক্টটি কোন টাইপের মিডিয়া । ইন্টারফেইসের মাধ্যমে ফরমাল একটি স্ট্রাকচার দাড় করানোর কনসেপ্টটি ডিজাইন বাই কন্ট্র্যাক্ট হিসেবে পরিচিত ।
এরপর আমরা একটি মিডিয়া ফ্যাক্টরি ক্লাস ডিজাইন করবো যার একটি স্ট্যাটিক মেথড থাকবে factory() নামে । এই মেথডে আমরা টাইপ পাস করে দিলে সে আমাদের ঐ টাইপের অবজেক্ট দিবে । স্ট্যাটিক মেথড ব্যবহার করবো যাতে নতুন অবজেক্ট তৈরি করার জন্য ফ্যাক্টরি অবজেক্ট এর কোন ইনস্ট্যান্স তৈরি করা না লাগে । আমরা যাতে সরাসরি MediaFactory::factory() কল করতে পারি সেজন্যই স্ট্যাটিক মেথড ।
আমরা এখন খুব সাধারণ একটি উদাহরণ দেখবো পিএইচপি তে –
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
<?php /** * Author: Abu Ashraf Masnun * URL: http://masnun.me */ namespace DesignPatternExample; class MediaFactory { public static function factory($type) { $className = __NAMESPACE__ . '\\' . ucfirst($type); if (!class_exists($className)) { throw new \Exception('Class does not exist!'); } $object = new $className(); if ($object instanceof Media) { return $object; } else { throw new \Exception("The requested type is not a valid media type!"); } } } interface Media { public function getType(); } class Video implements Media { public function getType() { return "Video"; } } class Audio implements Media { public function getType() { return "Audio"; } } class Photo implements Media { public function getType() { return "Photo"; } } |
এখানে দেখুন, আমাদের একটি Media ইন্টারফেইস আছে যেটি একটি পাবলিক মেথড ডিফাইন করেছে getType() । আমাদের Audio, Video এবং Photo ক্লাস এই ইন্টারফেইসকে ইম্প্লিমেন্ট করেছে নিজের মত করে । MediaFactory ক্লাসের factory() আমাদের কাছে $type প্যারামিটার চায় । টাইপ বলে দিলে সে সেই টাইপের অবজেক্ট তৈরি করে রিটার্ন করে ।
এবার আমরা দেখি কিভাবে আমাদের কোডে এই ফ্যাক্টরি মেথড প্যাটার্ন ব্যবহার করবো –
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<?php /** * Author: Abu Ashraf Masnun * URL: http://masnun.me */ /// Put some class autoloading or require the other files manually here use DesignPatternExample\MediaFactory; $audio = MediaFactory::factory('audio'); var_dump($audio->getType()); $video = MediaFactory::factory('video'); var_dump($video->getType()); $photo = MediaFactory::factory('photo'); var_dump($photo->getType()); |
এখানে আমরা প্রতিবার MediaFactory এর কাছ থেকে আমাদের প্রয়োজনীয় টাইপের অবজেক্ট চেয়ে নিচ্ছি । এই কোডের আউটপুটটা কেমন হবে? আসুন দেখে নেই –
1 2 3 4 5 |
Lighthouse: ~/Codes/php → php test.php string(5) "Audio" string(5) "Video" string(5) "Photo" |
তো, এটাই হলো ফ্যাক্টরি প্যাটার্ন যেখানে একটি ফ্যাক্টরি মেথড আমাদের ফরমায়েশ মত অবজেক্ট তৈরি করে দেয় 🙂
11 replies on “ডিজাইন প্যাটার্ন – ফ্যাক্টরি মেথড”
ভালোতো, কাহিনীটা মোটামুটি মাথায় ঢুকসে কিন্তু এই ধরনের প্যাটার্নের রিয়েল লাইফ ইমপ্লিমেন্টেশন কি রকম হইতে পারে একটা এক্সাম্পল দিতে পারবেন ভাইজান?
মানে ঠিক কি এ এই ধরনের প্যাটার্ন কাজে লাগতে পারে অথবা যদি এমন কোনো একটা কমন কোডবেস দেখাইতে পারতেন যা এই ধরনের প্যাটার্ন ব্যাবহার করে তায়লে একটু গুতায়া দেখতাম
আমি angular.js ব্যাবহারের সময় এই ধরনের কোড ব্যাবহার করেছি –
কিন্তু কখনো সোর্স দেখি নাই যে এই টার সুবিধা কি বা ক্যান এমন ব্যাবহার করা হয়। এইটাও কি factory pattern এর একটা ইমপ্লিমেন্টেশন?
(আগেই বইলা নেই যে আমি শুধু ফ্যাক্টরী ওয়ার্ডটা দেইখা ভাবছি যে এইখানে ফ্যাক্টরী প্যাটার্ন কিনা? lol)
special thanks for the article, hoping to see more content on intermediate-advanced stuff like design patterns etc. in bangla 🙂
আমার কাছেও মনে হচ্ছে ওটা ফ্যাক্টরী প্যাটার্নই । রিয়েল লাইফের কথা বলতে গেলে Doctrine2 এক্সেপশন তৈরি করার জন্য এবং Zend_Form ফর্ম ইলিমেন্ট তৈরি করার জন্য ফ্যাক্টরী মেথড প্যাটার্ন ব্যবহার করে আমি যতদূর জানি । এছাড়াও বিভিন্ন ORM কিংবা Logger প্রজেক্টেও এই প্যাটার্ণ এর ব্যবহার থাকার কথা ।
রিয়েল লাইফ উদাহরন অনেক হতে পারে।
আসুন মাসনুনের Media interface টিকে একটউ পরিবর্তন করিঃ
interface Media
{
public function getType();
public function render();
}
class Video implements Media
{
public function getType()
{
return “Video”;
}
public function render(){
// Play Video
}
}
class Audio implements Media
{
public function getType()
{
return “Audio”;
}
public function render(){
// Play Audio
}
}
class Photo implements Media
{
public function getType()
{
return “Photo”;
}
public function render(){
// Display image
}
}
এবার আমরা MediaFactory কে আরেকটি ফ্যাক্টরি মেথড যোগ করি যেটা একটি ফাইল পাথ নিবে, তাহলে খুব সহজেই একটি ফাইল/মিডিয়া ব্রাউজার বানিয়ে ফেলতে পারব আমরা! বলুন তো কিভাবে?
আসলে রিয়েল লাইফের অনেক উদাহরন দেয়া যায়, কিন্তু যা মাথায় আসছে তার সবই Abstract factory pattern দিয়ে 🙁
@masnun: Abstract factory pattern নিয়েও একটি পোস্টের অপেক্ষায় থাকলাম! আমার তো মনে হয়ে factory pattern এর সম্পূরক এটা।
জ্বী ভাইয়া, সময় করে Abstract Factory নিয়েও লিখবো ইনশাআল্লাহ । আসলে যেগুলো জানি সবগুলো নিয়েই লেখার ইচ্ছা আছে ।
সুন্দর লিখেছ মাসনুন…ইন্টারফেস এর ব্যবহার বলার সময় Design by Contract টার্ম টা উল্লেখ করে একটা রেফারেন্স লিঙ্ক দিয়ে দিতে পারো 🙂
ধন্যবাদ ভাইয়া । রেফারেন্স যোগ করে দিলাম ।
সুন্দর লেখা হইছে মাসনুন। ফ্যাক্টরি প্যাটার্নটা খুবই কাজের জিনিস। একবার আয়ত্তে চলে আসলে, এটা ছাড়া চলাটাই কঠিন হয়ে যায়। অন্যান্য ক্রিয়েশনাল প্যাটার্ন গুলো নিয়েও লিখো – তাহলে পাঠকরা প্যাটার্নগুলোর মধ্যে তুলনা করে, কখন কোনটা ব্যাবহার করতে হবে তা বুঝতে পারবে। আর সানী আমান এর কমেন্ট অনুযায়ী পোস্টটাকে আরেকটু এক্সটেন্ড করলে মনে হয় ভালো হবে। আর যেহেতু ডিসাইন প্যাটার্ন নিয়ে এইটা তোমার প্রথম লেখা, ইন্টারফেস এবং ডিসাইন বাই কন্ট্রাক্ট সম্পর্কেও আরেকটু বিশদ আলোচনা করলে নতুন পাঠকের বুঝতে সুবিধা হবে।
তোমার লেখার হাত ভালো। চালিয়ে যাও (Y)
ধন্যবাদ ভাইয়া ।
ডিজাইন বাই কন্ট্র্যাক্ট নিয়ে আলাদা করে লেখার ইচ্ছা আছে ।
Masnun, A little correction. In an interface no access modifier should be used to define a method signature . Cause method signatures in an interface are always public 🙂 It’s just a convention I had learned 🙂
I agree to the fact that it should be public but I am a little skeptic about using no modifiers at all.
[…] ফ্যাক্টরী মেথড ডিজাইন প্যাটার্ণ – আবু আশরাফ মাসনুন […]