পাঠ ১০ · ৫৭-এর মধ্যে · মডিউল ৩

মোবাইল অ্যাপের জন্য MVC

MVC for mobile apps
৯ মিনিট পড়া মধ্যম · Intermediate Python কোডসহ সম্পূর্ণ বাংলায়

এই পাঠে যা শিখবেন

  • ওয়েব MVC (FSWF L05) থেকে মোবাইল MVC-এর ঠিক কী পার্থক্য — ট্রিগার হিসেবে HTTP রিকোয়েস্টের বদলে টাচ ইভেন্ট
  • একটি কনক্রিট প্রোফাইল স্ক্রিনের জন্য Model, View, Controller-এর দায়িত্ব ভাগ
  • একটি সত্যিকারের "নাম এডিট" ইন্টারঅ্যাকশন Controller → Model → View → re-render পথে ট্রেস করা
  • কেন MVC-তে Controller-কে re-render নিয়ে স্পষ্ট সিদ্ধান্ত নিতে হয় — পরের পাঠগুলোর ভিত্তি

১ · মোবাইল স্ক্রিনে MVC — ট্রিগার আলাদা, চক্র একই

FSWF কোর্সের L05-এ শেখানো হয়েছে কীভাবে Model ডেটা ও বিজনেস লজিক ধারণ করে, View শুধু প্রদর্শন করে, আর Controller মাঝে সমন্বয়ক হিসেবে কাজ করে। ওয়েবে এই চক্রটি শুরু হয় একটি HTTP রিকোয়েস্ট দিয়ে। মোবাইল স্ক্রিনে HTTP রিকোয়েস্ট নেই — বরং চক্রটি শুরু হয় একটি টাচ ইভেন্ট দিয়ে (যেমন একটি "Edit" বাটনে ট্যাপ করা) — বাকি দায়িত্ব-বণ্টন হুবহু একই থাকে।

টাচ ইভেন্ট ইউজার "Edit" বাটনে ট্যাপ করলো ProfileController on_edit_name(new_name) ProfileModel set_name() -- ডেটা আপডেট ProfileView render(model) -- re-render
Controller টাচ ইভেন্ট গ্রহণ করে Model আপডেট করে, তারপর স্পষ্টভাবে View-কে নতুন Model দিয়ে রি-রেন্ডার করতে বলে।
Model
প্রোফাইলের ডেটা (নাম, ইমেইল) ও তা পরিবর্তনের নিয়ম ধারণ করে — কোনো UI জ্ঞান রাখে না।
View
বর্তমান Model অনুযায়ী স্ক্রিনে যা দেখানো হবে তা প্রিন্ট/রেন্ডার করে — সম্পূর্ণ প্যাসিভ, নিজে কিছু সিদ্ধান্ত নেয় না।
Controller
টাচ ইভেন্ট গ্রহণ করে, Model-কে আপডেট করতে বলে, তারপর স্পষ্টভাবে View-কে রি-রেন্ডার করতে বলে।

২ · প্রোফাইল স্ক্রিনের MVC — বাস্তব কোড

নিচের কোড সেলে তিনটি ক্লাস — ProfileModel, ProfileView, ProfileController। Controller.on_edit_name() কল করে দেখা যাক ইউজার নাম এডিট করলে কী ঘটে — এবং একই নাম দিয়ে আবার এডিট করলে Controller কী করে (MVVM থেকে এটি ভিন্ন — পরের পাঠে বিস্তারিত)।

Python
# ---------- MODEL -- শুধু ডেটা ও তার পরিবর্তনের নিয়ম, UI সম্পর্কে কিছুই জানে না ----------
class ProfileModel:
    def __init__(self, name, email):
        self.name = name
        self.email = email

    def set_name(self, new_name):
        self.name = new_name


# ---------- VIEW -- সম্পূর্ণ প্যাসিভ, যা দেওয়া হয় তাই প্রিন্ট করে ----------
class ProfileView:
    def __init__(self):
        self.render_count = 0

    def render(self, model):
        self.render_count += 1
        print(f"[View render #{self.render_count}] নাম: {model.name} | ইমেইল: {model.email}")


# ---------- CONTROLLER -- টাচ ইভেন্ট গ্রহণ করে, Model আপডেট করে, স্পষ্টভাবে View-কে রি-রেন্ডার করতে বলে ----------
class ProfileController:
    def __init__(self, model, view):
        self.model = model
        self.view = view
        self.view.render(self.model)   # স্ক্রিন প্রথমবার খোলার সময়কার রেন্ডার

    def on_edit_name(self, new_name):
        print(f"টাচ ইভেন্ট: ইউজার 'Edit' বাটনে ট্যাপ করে নাম দিলো -> '{new_name}'")
        self.model.set_name(new_name)
        self.view.render(self.model)   # Controller নিঃশর্তে re-render নির্দেশ দেয়


print("== প্রোফাইল স্ক্রিন খোলা হলো ==")
model = ProfileModel("করিম হোসেন", "karim@example.com")
view = ProfileView()
controller = ProfileController(model, view)   # render #1 -- প্রাথমিক

print("\n== ইউজার নাম এডিট করলো ==")
controller.on_edit_name("রহিম উদ্দিন")          # render #2 -- নতুন নাম

print("\n== ইউজার একই নাম আবার সাবমিট করলো (কোনো প্রকৃত পরিবর্তন নেই) ==")
controller.on_edit_name("রহিম উদ্দিন")          # render #3 -- MVC-তে এটিও রি-রেন্ডার হয়

print(f"\nমোট রি-রেন্ডার হয়েছে: {view.render_count} বার")

    
লক্ষ্য করুন তৃতীয়বার একই নাম ("রহিম উদ্দিন") দিয়ে এডিট করলেও View আবার রি-রেন্ডার হয় (render #3) — কারণ ProfileController.on_edit_name() কোনো "মান আসলেই বদলেছে কি না" চেক করে না, শুধু নিঃশর্তে view.render() কল করে। মোট রি-রেন্ডার সংখ্যা তাই ৩ — যদিও প্রকৃত ডেটা মাত্র একবার বদলেছে। পরের পাঠে (MVVM) দেখা যাবে কীভাবে একটি Observable প্যাটার্ন এই অপ্রয়োজনীয় রি-রেন্ডার এড়াতে পারে।
মূল কথা · Key takeaway

মোবাইল MVC-তে চক্রটি ওয়েব MVC-এর মতোই — Model/View/Controller-এর দায়িত্ব একই — শুধু চক্রের ট্রিগার HTTP রিকোয়েস্টের বদলে একটি টাচ ইভেন্ট, এবং Controller রি-রেন্ডার করার সিদ্ধান্তটি নিজেই স্পষ্টভাবে নেয়। এই "Controller-চালিত, নিঃশর্ত রি-রেন্ডার" ধরনটাই MVVM ও MVI-এর সাথে মূল পার্থক্যের জায়গা — পরের দুই পাঠে বিস্তারিত।

ভাবনার প্রশ্ন

প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।

প্র ০১ ওয়েব MVC-তে Controller একটি HTTP রিকোয়েস্ট থেকে ট্রিগার হয়; মোবাইলে কী থেকে?

একটি টাচ ইভেন্ট থেকে — যেমন একটি বাটনে ট্যাপ, একটি সোয়াইপ, বা একটি ফর্ম সাবমিট বাটনে চাপ। ওয়েবে প্রতিটি রিকোয়েস্ট একটি নতুন পেজ-লোড চক্র শুরু করে; মোবাইলে স্ক্রিনটি ইতিমধ্যেই মেমোরিতে চলছে এবং টাচ ইভেন্টটি সরাসরি সেই একই চলমান Controller ইনস্ট্যান্সের একটি মেথড কল করে — নতুন করে কিছু "লোড" হয় না।

প্র ০২ উপরের কোডে ProfileModel কেন ProfileView-এর কোনো রেফারেন্স রাখে না?

MVC-তে Model শুধু ডেটা ও ডেটা পরিবর্তনের নিয়ম ধারণ করে — এটি জানে না, এবং জানার দরকারও নেই, কে বা কীভাবে তা প্রদর্শন করছে। এই বিচ্ছিন্নতাই Model-কে টেস্ট করা সহজ করে (কোনো UI ছাড়াই) এবং একই Model-কে ভবিষ্যতে একাধিক ভিন্ন View (যেমন ফোন বনাম ট্যাবলেট লেআউট) দিয়ে ব্যবহার করার পথ খোলা রাখে।

প্র ০৩ যদি ProfileController.on_edit_name()-এর ভেতর self.view.render(...) কলটি ভুলে বাদ পড়ে যায়, তাহলে কী ঘটবে?

self.model.set_name(new_name) ঠিকই চলবে — Model-এর ভেতরের name সত্যিই বদলে যাবে — কিন্তু স্ক্রিনে কোনো পরিবর্তন দেখা যাবে না, কারণ View-কে কেউ জানায়নি যে ডেটা বদলেছে। এটিই MVC-এর একটি বাস্তব ঝুঁকি — Controller-কেই মনে রেখে প্রতিটি জায়গায় রি-রেন্ডার ট্রিগার করতে হয়; ভুলে গেলে ডেটা ও UI অসামঞ্জস্যপূর্ণ ("stale UI") হয়ে যায়।

অনুশীলন

  1. চিন্তা করুন: উপরের প্রোফাইল স্ক্রিনে যদি ইমেইল এডিট করারও একটি ফিচার যোগ করতে হয়, তাহলে MVC কাঠামোতে কোথায় কোথায় কোড লিখতে হবে বলে মনে হয় — Model-এ, View-এ, নাকি Controller-এ?

    তিন জায়গাতেই ছোট সংযোজন লাগবে: ProfileModel-এ একটি set_email() মেথড, ProfileView.render()-এ ইমেইল প্রদর্শনের লজিক (যা ইতিমধ্যেই আছে), এবং ProfileController-এ একটি নতুন on_edit_email(new_email) মেথড যা on_edit_name()-এর মতোই Model আপডেট করে View রি-রেন্ডার করবে। প্রতিটি নতুন ইন্টারঅ্যাকশনের জন্য Controller-এ একটি নতুন হ্যান্ডলার মেথড লাগে — এটিই MVC-এর একটি সীমাবদ্ধতা, যত বেশি ইন্টারঅ্যাকশন, Controller তত বড় হতে থাকে ("Massive Controller" সমস্যা নামে পরিচিত)।

  2. পরীক্ষা করুন: উপরের কোড সেলে ProfileController.on_edit_name()-এর ভেতর if new_name == self.model.name: return — এই লাইনটি self.model.set_name(new_name)-এর আগে যোগ করুন, তারপর কোডটি আবার চালিয়ে দেখুন মোট রি-রেন্ডার সংখ্যা কত হয়।

    এই গার্ড-ক্লজ যোগ করার পর তৃতীয় কলটি ("রহিম উদ্দিন" আবার দিয়ে) সাথে সাথে return করবে, কোনো set_name() বা view.render() চলবে না — মোট রি-রেন্ডার সংখ্যা ৩ থেকে কমে ২-এ নেমে আসবে। এটি ঠিক MVVM-এর Observable.set() ভেতরের old_value != new_value চেকের মতোই যুক্তি — শুধু এখানে সেই চেকটি Controller-এ ম্যানুয়ালি লিখতে হয়েছে, MVVM-এ এটি ফ্রেমওয়ার্কের অংশ হিসেবে স্বয়ংক্রিয়ভাবে আসে (পরের পাঠে বিস্তারিত)।

আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ

  • কোর্সের সম্পূর্ণ সিলেবাস দেখুন ৫৭টি পাঠ অ্যাপ লাইফসাইকেল, মোবাইল UI/UX, MVVM/MVI আর্কিটেকচার, নেটিভ বনাম ক্রস-প্ল্যাটফর্ম, নেভিগেশন, স্টেট ম্যানেজমেন্ট, লোকাল স্টোরেজ, ডিভাইস ফিচার ও ডিপ্লয়মেন্ট — বাকি পাঠগুলো শীঘ্রই যুক্ত হবে।
  • FSWF · The MVC Architecture Pattern সহোদর পাঠ MVC-এর সাধারণ সংজ্ঞা ও ওয়েব-প্রেক্ষাপটের বিস্তারিত এই পাঠেই তৈরি হয়েছে।
  • সব Courses দেখুন ABCL TECH C, C++, Python, Java, JavaScript, DSA, DBMS, Discrete Mathematics, System Design, Cybersecurity, Cloud Computing & DevOps, Computer Networks, Operating Systems, Computer Architecture, Programming Languages & Compiler Design, Software Engineering & Git, Theory of Computation, Engineering Economics, Full-Stack Web Frameworks ও Mobile App Development — সব এক জায়গায়।
আগের পাঠ
ডার্ক মোড ও থিমিং