Categories
Bangla

এমভিসি (মডেল-ভিউ-কন্ট্রোলার) প্যাটার্ণ

এমভিসি বা মডেল-ভিউ-কন্ট্রোলার খুবই জনপ্রিয় একটি প্যাটার্ন । বিশেষ করে যদি আপনি ওয়েব নিয়ে কাজ করেন তাহলে হয়তো ইতোমধ্যে এমভিসি শব্দটির সাথে পরিচিত হয়েছেন । Trygve Reenskaug নামের এক ভদ্রলোক এই প্যাটার্নটির জনক। ভদ্রলোকের নামের বানানটি যতটা না জটিল, তার আইডিয়াটা ঠিক ততটাই সহজবোধ্য । এমভিসি প্যাটার্নের মূল বক্তব্য হলো এই প্যাটার্নে তিনটি কম্পোনেন্ট থাকবে – একটি মডেল যেটি ডাটা নিয়ে কাজ করবে, একটি ভিউ যেটার কাজ হবে মডেলকে ভিজ্যুয়ালাইজ করা এবং একটি কন্ট্রোলার যেটি ব্যবহারকারী এবং সিস্টেমের মধ্য সমন্বয়কারী হিসেবে কাজ করে । Reenskaug এমভিসি প্যাটার্নের উপর একটি ওয়েব পেইজ মেইনটেইন করেন যেখানে এমভিসি এর উপরে বিশদ বর্ননা পাওয়া যাবে – http://heim.ifi.uio.no/~trygver/themes/mvc/mvc-index.html

আমরা যদি এমভিসি কম্পোনেন্টগুলোর দিকে নজর দেই তাহলে দেখবো –

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

ভিউ: ভিউ এর কাজ হচ্ছে মডেলকে ব্যবহারকারীর সামনে তুলে ধরা । সাধারণত ভিউ মডেল থেকে ডাটা নিয়ে সেটাকে ব্যবহারকারীর কাছে সহজবোধ্য রূপে তুলে ধরে ।

কন্ট্রোলার: কন্ট্রোলার ব্যবহারকারীর কাছ থেকে তথ্য সংগ্রহ করে আবার ব্যবহারকারীর প্রয়োজনমত ভিউ উপস্থাপন করে । কন্ট্রোলারই বলে দেয় ভিউ কোন মডেল থেকে ডাটা নিয়ে কিভাবে উপস্থাপন করবে । এছাড়াও কন্ট্রোলার মডেলে নানা ধরণের পরিবর্তন করতে পারে প্রয়োজনমত ।

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

উদাহরণ হিসেবে আমরা যদি একটি সাদামাটা স্ট্যাটিক ওয়েব পেইজের কথা চিন্তা করি তাহলে দেখবো –

# মডেল: এইচটিএমএল এখানে মডেল হিসেবে কাজ করছে । ওয়েব পেইজের সকল তথ্য কিন্তু এইচটিএমএল হিসেবেই থাকছে ।
# ভিউ: এই এইচটিএমএল ট্যাগগুলোকে কিভাবে ব্যবহারকারীর সামনে তুলে ধরতে হবে সেটা নির্দেশ করার জন্য আমরা সিএসএস ব্যবহার করি ।
# কন্ট্রোলার: জাভাস্ক্রীপ্ট ব্যবহার করে আমরা নতুন নতুন এইচটিএমএল যেমন যোগ করতে পারি তেমনি পারি সিএসএস পরিবর্তন করতে ।

তাহলে এখানেও সেই এমভিসি প্যাটার্নের দেখা মিলছে । এবার দেখা যাক একটি ডাইনামিক ওয়েব এ্যাপ্লিকেশন এর ক্ষেত্রে কি হতে পারে । মনে করি একটি ওয়েব এ্যাপ্লিকেশন যেটির কাজ হচ্ছে একটি ক্লাসের স্টুডেন্টদের তালিকা প্রদশর্ন করা । তাহলে –

# মডেল: সকল স্টুডেন্টদের তথ্য । সম্ভবত এই তথ্য একত্রে একটি ডাটাবেইজে সংরক্ষিত থাকবে এবং মডেল ব্যবহার করে আমরা এই তথ্য এ্যাক্সেস করতে পারবো ।
# ভিউ: স্টুডেন্টদের তালিকা যেটি কিনা এইচটিএমএল হিসেবে একটি সুন্দর টেবিলে রোল নম্বরের ক্রমানুযায়ী প্রদর্শিত হবে ।
# কন্ট্রোলার: কন্ট্রোলার জানবে কোন মডেল থেকে স্টুডেন্টদের ডাটা সংগ্রহ করতে হবে, রোল নম্বর অনুযায়ী কিভাবে সাজাতে হবে অতপর কিভাবে এই ডাটা থেকে ব্রাউজারে প্রদর্শনযোগ্য এইচটিএমএল কোড আউটপুট করা যাবে ।

আমরা যদি হালের জনপ্রিয় পিএইচপি ফ্রেমওয়ার্ক লারাভেলের মত করে চিন্তা করি তাহলে দেখবো –

# মডেল অবজেক্টগুলো সরাসরি ডাটাবেইজের টেবিলকে রিপ্রেজেন্ট করে । একেকটি মডেল ব্যবহার করে আমরা একেক টেবিল থেকে ডাটা এ্যাক্সেস করতে পারি ।
# ভিউ থাকে এইচটিএমএল এর মত বিশেষ টেম্প্লেট যেটা জানে কিভাবে এইচটিএমএল কোড আউটপুট করতে হবে ।
# কন্ট্রোলার অবজেক্টগুলো ব্যবহারকারীর ইচ্ছামত প্রয়োজনীয় মডেল থেকে ডাটা এনে ভিউ তৈরি করে দেয় ।

যেমন: যখন একজন ব্যবহারকারী /students/all – এই ঠিকানা ভিজিট করবেন তখন সব স্টুডেন্টদের তালিকা দেখাতে হবে । যখনই ওয়েব এ্যাপ্লিকশেন এই রিকোয়েস্টটি পায় তখন সে কন্ট্রোলারকে জানায় যে ব্যবহারকারী সব স্টুডেন্টদের তালিকা দেখতে চাচ্ছে । কন্ট্রোলার তখন ঝটপট Student মডেল এর কাছ থেকে সব স্টুডেন্ট এর তথ্য সংগ্রহ করে নেয় । এরপর সেগুলোকে রোল অনুযায়ী সাজিয়ে পাঠিয়ে দেয় ভিউ এর কাছে । ভিউ তখন মডেল হতে পাওয়া ডাটা সুন্দর করে এইচটিএমএল হিসেবে আউটপুট দিয়ে দেয় ।

কি করে বুঝবেন যে আপনার এ্যাপ্লিকেশনটি সঠিকভাবে এমভিসি প্যাটার্ন অনুসরণ করছে? নিজেকে জিজ্ঞাসা করুন এই এ্যাপ্লিকেশনটি থীমেবল কিনা । অর্থাৎ চাইলেই আপনি এটির জন্য অনেকগুলো থীম তৈরি করে ডাইনামিকালি থীম পরিবর্তন করতে পারছেন কিনা । যদি সেটা সম্ভব হয় তবে সম্ভবত আপনি সঠিকভাবেই এমভিসি ফলো করেছেন আর যদি সম্ভব না হয় তবে আপনি এমভিসি কম্পোনেন্টগুলোকে আলাদা করতে পারেননি ঠিকমতো ।

Categories
Bangla PHP

ডিজাইন প্যাটার্ন – ফ্যাক্টরি মেথড

আপডেট:

রিফাত ভাইয়ের সাজেশন অনুসারে দুটো জিনিস যোগ করলাম –

# namespace এর ব্যবহার
# instanceof ব্যাবহার করে নিশ্চিত হওয়া যে রিকোয়েস্ট করা ক্লাস আসলে মিডিয়া ইন্টারফেইস ইম্প্লিমেন্ট করে ।

এমরান ভাইয়ের পরামর্শ অনুসারে ডিজাইন বাই কন্ট্র্যাক্ট এর রেফারেন্স যোগ করলাম ।


ফ্যাক্টরি মেথড প্যাটার্ন এর কাজ তার নাম থেকেই সহজে অনুমান করা যায় । এই প্যাটার্নে একটি ফ্যাক্টরি অবজেক্ট এ একটি মেথড থাকে যার কাজ হচ্ছে আমাদের প্রয়োজনমত অবজেক্ট তৈরি করে দেওয়া । এই অবজেক্টগুলো সাধারণত একই ধরণের হয়ে থাকে । উদাহরণ হিসেবে আমরা ভাবতে পারি একটি কন্টেন্ট ম্যানেজমেন্ট সলিউশন এর কথা (যেমন: ওয়ার্ডপ্রেস, জুমলা কিংবা দ্রুপাল) যেখানে নানা ধরণের কন্টেন্ট থাকে । থাকতে পারে অডিও, ভিডিও কিংবা ফটো । এগুলোকে এক সাথে আমরা মিডিয়া হিসেবে চিন্তা করতে পারি । আবার দেখুন, এই মিডিয়াগুলোর কিছু সাধারণ বৈশিষ্ট্য থাকতে পারে, যেমন: সব মিডিয়ারই একটি পাবলিক URL থাকে, সার্ভারে লোকেশন বোঝানোর জন্য ফাইল পাথ থাকে, মিডিয়ার ফাইল সাইজ থাকে, সেই সাথে থাকে কোনটি কোন টাইপের মিডিয়া । এরকম ক্ষেত্রে আমরা একটি মিডিয়া ইন্টারফেইস তৈরি করে নিবো এবং আমাদের স্বতন্ত্র মিডিয়াগুলো এই ইন্টারফেইস ইম্প্লিমেন্ট করবে । ইন্টারফেইস ব্যবহার করে আমরা অবজেক্টগুলোর সাধারণ আচরণ নির্দিষ্ট করে দিতে পারি । যেমন আমরা সব গুলো অবজেক্টকে বাধ্য করতে পারি একটি getType() মেথড ইম্প্লিমেন্ট করতে যেটা আমাদের বলে দিবে ঐ অবজেক্টটি কোন টাইপের মিডিয়া । ইন্টারফেইসের মাধ্যমে ফরমাল একটি স্ট্রাকচার দাড় করানোর কনসেপ্টটি ডিজাইন বাই কন্ট্র্যাক্ট হিসেবে পরিচিত ।

এরপর আমরা একটি মিডিয়া ফ্যাক্টরি ক্লাস ডিজাইন করবো যার একটি স্ট্যাটিক মেথড থাকবে factory() নামে । এই মেথডে আমরা টাইপ পাস করে দিলে সে আমাদের ঐ টাইপের অবজেক্ট দিবে । স্ট্যাটিক মেথড ব্যবহার করবো যাতে নতুন অবজেক্ট তৈরি করার জন্য ফ্যাক্টরি অবজেক্ট এর কোন ইনস্ট্যান্স তৈরি করা না লাগে । আমরা যাতে সরাসরি MediaFactory::factory() কল করতে পারি সেজন্যই স্ট্যাটিক মেথড ।

আমরা এখন খুব সাধারণ একটি উদাহরণ দেখবো পিএইচপি তে –

এখানে দেখুন, আমাদের একটি Media ইন্টারফেইস আছে যেটি একটি পাবলিক মেথড ডিফাইন করেছে getType() । আমাদের Audio, Video এবং Photo ক্লাস এই ইন্টারফেইসকে ইম্প্লিমেন্ট করেছে নিজের মত করে । MediaFactory ক্লাসের factory() আমাদের কাছে $type প্যারামিটার চায় । টাইপ বলে দিলে সে সেই টাইপের অবজেক্ট তৈরি করে রিটার্ন করে ।

এবার আমরা দেখি কিভাবে আমাদের কোডে এই ফ্যাক্টরি মেথড প্যাটার্ন ব্যবহার করবো –

এখানে আমরা প্রতিবার MediaFactory এর কাছ থেকে আমাদের প্রয়োজনীয় টাইপের অবজেক্ট চেয়ে নিচ্ছি । এই কোডের আউটপুটটা কেমন হবে? আসুন দেখে নেই –

তো, এটাই হলো ফ্যাক্টরি প্যাটার্ন যেখানে একটি ফ্যাক্টরি মেথড আমাদের ফরমায়েশ মত অবজেক্ট তৈরি করে দেয় 🙂

Categories
Bangla Python

পাইথনে সিঙ্গলটন প্যাটার্ন

সিঙ্গলটন প্যাটার্ন ব্যবহার করে আমরা নিশ্চিত করতে পারি যেন একটি ক্লাস থেকে একটিই মাত্র অবজেক্ট তৈরি করা হয় । সচরাচর আমরা একই ক্লাস থেকে প্রয়োজনমত ইনস্ট্যান্স তৈরি করে নেই । কিন্তু কখনো কখনো প্রয়োজন পড়ে সিস্টেমওয়াইড একই ইনস্ট্যান্স ব্যবহার করার কিংবা কখনো কখনো নতুন ইনস্ট্যান্স তৈরি করা বেশ রিসোর্স ইন্টেন্সিভ হয় । এরকম পরিস্থিতিতে আমরা সিঙ্গলটন প্যাটার্ন ব্যবহার করতে পারি । এর বাস্তব উদাহরণ হতে পারে ডাটাবেইজ কানেকশন । আমরা চাইবো আমাদের এ্যাপ্লিকেশন যেন একবারই ডাটাবেইজ এ কানেক্ট করে এবং পরে ঐ কানেকশনটিই বারবার ব্যবহার করে ।

পাইথনে সিঙ্গলটন প্যাটার্নটা বেশ কয়েকভাবে করা যায় । তবে সবচাইতে গ্রহনযোগ্য উপায় হচ্ছে ডেকোরেটর ব্যবহার করা । আমরা প্রথমেই কোড দেখে নেই –

পাইথনে ডেকোরেটর আসলে callable অবজেক্ট যেটি অন্য একটি অবজেক্টকে আর্গুমেন্ট হিসেবে গ্রহন করে এবং এবং আরেকটি অবজেক্ট রিটার্ন করে । কোন ক্লাস বা ফাংশন এর উপর @ চিহ্ন সহ ডেকোরেটরের নাম লিখে আমরা ডেকোরেটর ব্যবহার করি । ডেকোরেটর কে আমরা সহজে এভাবে কল্পনা করতে পারি –

এর মানে দাড়াবে অনেকটা এরকম –

তো এই জিনিসটিই আমরা সিঙ্গলটন প্যাটার্ন তৈরি করতে ব্যবহার করছি । প্রথমে আমরা একটি ক্লাস বেইজড ডেকোরেটর ডিফাইন করলাম এবং তারপর আমাদের Person ক্লাসে ডেকোরেটর এ্যাপ্লাই করলাম । আসলে কি ঘটছে এখানে? ব্যাপারটা আসলে অনেকটা এরকম –

হয়ে যাচ্ছে –

আমরা আর চাইলেও Person ইনস্ট্যান্স তৈরি করতে পারবো না । তাই বাধ্য হয়ে আমরা Instance() কল করবো । আসলে আমাদের কলটি হবে অনেকটা এরকম –

singleton ক্লাস টি __init__ করার সময়ই আদি এবং অকৃত্রিম Person ক্লাসটি পাস করে দেওয়া হয় যেটি self._decorated এ থেকে যায় । এরপর Instance() মেথডের কাজ বেশ সহজ সরল । সে দেখে আগেই ইনস্ট্যান্স তৈরি করা আছে কিনা । না থাকলে self._decorated এ থাকা মূল ক্লাস থেকে একটি ইনস্ট্যান্স করে রিটার্ন করে এবং নিজের কাছে self._instance এ সেইভ করে ।

ক্লাস বেইজড ডেকোরেটর বুঝতে সমস্যা হলে এভাবে এক্সপেরিমেন্ট করে দেখা যায় –