পাঠ ১২ · ৫৮-এর মধ্যে · মডিউল ৩
Home / Courses / Software Engineering Principles & Git / রিকোয়ারমেন্ট ইঞ্জিনিয়ারিং

ইউজ কেস ও ইউজ কেস ডায়াগ্রাম

Use cases & use case diagrams
৮ মিনিট পড়া শুরু · Beginner Python কোডসহ সম্পূর্ণ বাংলায়

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

  • ইউজ কেস কী এবং এটি কীভাবে L11-এর ফাংশনাল রিকোয়ারমেন্টের একটি বিস্তৃত, বাস্তবসম্মত সংস্করণ
  • একটি স্ট্যান্ডার্ড ইউজ কেসের পাঁচটি অংশ — অ্যাক্টর, প্রিকন্ডিশন, মেইন ফ্লো, অল্টারনেটিভ ফ্লো, পোস্টকন্ডিশন
  • UML ইউজ কেস ডায়াগ্রামের বেসিক ভিজ্যুয়াল নোটেশন
  • Python দিয়ে একটি সম্পূর্ণ "পাসওয়ার্ড রিসেট" ইউজ কেস বাস্তবে তৈরি ও প্রিন্ট করা

১ · ইউজ কেস কী

ইউজ কেসUse Caseএকজন অ্যাক্টর কীভাবে একটি নির্দিষ্ট লক্ষ্য অর্জনের জন্য সিস্টেমের সাথে মিথস্ক্রিয়া করে, তার একটি কাঠামোবদ্ধ, ধাপে-ধাপে বর্ণনা। হলো একজন অ্যাক্টরActorএকজন ইউজার অথবা একটি বাহ্যিক সিস্টেম, যে সিস্টেমের সাথে মিথস্ক্রিয়া শুরু করে। — একজন ইউজার বা একটি বাহ্যিক সিস্টেম — সিস্টেমের সাথে মিথস্ক্রিয়া করে ঠিক কোন একটি নির্দিষ্ট লক্ষ্য অর্জনের চেষ্টা করছে তার একটি কাঠামোবদ্ধ বর্ণনা। L11-এ আমরা দেখেছি ফাংশনাল রিকোয়ারমেন্ট বলে "সিস্টেম শ্যাল ইউজারকে ইমেইলের মাধ্যমে পাসওয়ার্ড রিসেট করতে দেবে" — একটি ইউজ কেস এই একই আইডিয়াকে একটি পূর্ণাঙ্গ, ধাপে-ধাপে কাহিনিতে বিস্তৃত করে, ঠিক কীভাবে সেই মিথস্ক্রিয়াটি ঘটে তা বর্ণনা করে — সাধারণ ফ্লো এবং কী কী ভুল হতে পারে দুটোই সহ।

২ · স্ট্যান্ডার্ড ইউজ কেস স্ট্রাকচার

একটি ইউজ কেস সাধারণত পাঁচটি নির্দিষ্ট অংশে লেখা হয় — এটি একটি বাস্তব, ব্যাপকভাবে ব্যবহৃত টেমপ্লেট:

অ্যাক্টর (Actor)
কে এই ইউজ কেসটি শুরু করে — একজন ইউজার, অ্যাডমিন, অথবা একটি বাহ্যিক সিস্টেম।
প্রিকন্ডিশন (Preconditions)
এই ইউজ কেস শুরু হওয়ার আগে কী কী শর্ত অবশ্যই সত্য হতে হবে।
মেইন ফ্লো (Main flow)
সবচেয়ে সাধারণ, সফল ধাপে-ধাপে সিকোয়েন্স — "বেসিক পাথ"।
অল্টারনেটিভ ফ্লো (Alternative flows)
ব্যতিক্রম, এরর কেস, ও বিকল্প পরিস্থিতি — যেমন "ভুল পাসওয়ার্ড দেওয়া হলে কী হয়"।
পোস্টকন্ডিশন (Postconditions)
ইউজ কেস সফলভাবে শেষ হওয়ার পরে কী সত্য হয়ে যায়।

৩ · ইউজ কেস ডায়াগ্রাম — UML-এর একটি ঝলক

ইউজ কেস ডায়াগ্রামUse Case DiagramUML-এর একটি ভিজ্যুয়াল নোটেশন — অ্যাক্টরদের স্টিক-ফিগার হিসেবে ও ইউজ কেসগুলোকে ওভাল হিসেবে দেখিয়ে সিস্টেমের কার্যকারিতার একটি হাই-লেভেল ম্যাপ তৈরি করে। একটি হাই-লেভেল ভিজ্যুয়াল উপস্থাপনা — অ্যাক্টরদের স্টিক ফিগার হিসেবে, ইউজ কেসগুলোকে ওভাল হিসেবে, এবং লাইন দিয়ে দেখানো হয় কোন অ্যাক্টর কোন ইউজ কেসে অংশগ্রহণ করে। এটি ইমপ্লিমেন্টেশনের কোনো ডিটেইল না দেখিয়ে সিস্টেমের কার্যকারিতার একটি ব্যবহারকারী-কেন্দ্রিক মানচিত্র দেয় — M4/L19-এ আমরা UML-এর আরও দুটি ডায়াগ্রাম টাইপ (ক্লাস ও সিকোয়েন্স) দেখব, যেগুলো এই ইউজ কেস ডায়াগ্রামের নোটেশনকে বিস্তৃত করে।

ইউজার অ্যাডমিন Login System লগইন করা পাসওয়ার্ড রিসেট ইউজার অ্যাকাউন্ট ব্লক করা
"ইউজার" অ্যাক্টর "লগইন করা" ও "পাসওয়ার্ড রিসেট" ইউজ কেসে অংশগ্রহণ করে, আর শুধু "অ্যাডমিন" অ্যাক্টর "ইউজার অ্যাকাউন্ট ব্লক করা" ইউজ কেসে অংশগ্রহণ করে — একটি হাই-লেভেল, ইমপ্লিমেন্টেশন-মুক্ত ম্যাপ।
M4/L19-এর সাথে সম্পর্ক

এই লেসনের ইউজ কেস ডায়াগ্রাম UML-এর সবচেয়ে সরল ডায়াগ্রাম টাইপগুলোর একটি — সিস্টেম কী করে তার একটি হাই-লেভেল ম্যাপ। M4/L19-এ আমরা দেখব ক্লাস ডায়াগ্রাম (সিস্টেমের স্ট্যাটিক গঠন) ও সিকোয়েন্স ডায়াগ্রাম (একটি নির্দিষ্ট ইন্টারঅ্যাকশনের সময়ের সাথে ধাপে-ধাপে বিবরণ) — সিকোয়েন্স ডায়াগ্রাম আসলে এই লেসনের একটি ইউজ কেসের মেইন ফ্লোকেই আরও ভিজ্যুয়ালি নির্দিষ্টভাবে দেখানোর একটি উপায়।

৪ · একটি সম্পূর্ণ ইউজ কেস — কোড দিয়ে

নিচে "পাসওয়ার্ড রিসেট" ইউজ কেসটি একটি বাস্তব UseCase স্ট্রাকচারে পূর্ণাঙ্গভাবে তৈরি করা হলো, তারপর স্ট্যান্ডার্ড ফরম্যাটে প্রিন্ট করা হলো — লক্ষ্য করুন এটি একটি খালি টেমপ্লেট নয়, বরং বাস্তবসম্মত কনটেন্ট দিয়ে পূর্ণ।

Python
class UseCase:
    def __init__(self, name, actor, preconditions, main_flow, alternative_flows, postconditions):
        self.name = name
        self.actor = actor
        self.preconditions = preconditions
        self.main_flow = main_flow
        self.alternative_flows = alternative_flows
        self.postconditions = postconditions


def print_use_case(uc):
    print(f"ইউজ কেস: {uc.name}")
    print(f"অ্যাক্টর: {uc.actor}")

    print("\nপ্রিকন্ডিশন:")
    for p in uc.preconditions:
        print(f"  - {p}")

    print("\nমেইন ফ্লো:")
    for i, step in enumerate(uc.main_flow, start=1):
        print(f"  {i}. {step}")

    print("\nঅল্টারনেটিভ ফ্লো:")
    for scenario, steps in uc.alternative_flows.items():
        print(f"  [{scenario}]")
        for i, step in enumerate(steps, start=1):
            print(f"    {i}. {step}")

    print("\nপোস্টকন্ডিশন:")
    for p in uc.postconditions:
        print(f"  - {p}")


reset_password = UseCase(
    name="পাসওয়ার্ড রিসেট করা",
    actor="রেজিস্টার্ড ইউজার",
    preconditions=[
        "ইউজারের একটি ভ্যালিড, রেজিস্টার্ড অ্যাকাউন্ট আছে",
        "ইউজার লগইন পেজে আছে",
    ],
    main_flow=[
        "ইউজার 'পাসওয়ার্ড ভুলে গেছি' লিংকে ক্লিক করে",
        "সিস্টেম ইউজারের কাছে রেজিস্টার্ড ইমেইল ঠিকানা চায়",
        "ইউজার ইমেইল ঠিকানা লিখে সাবমিট করে",
        "সিস্টেম সেই ইমেইলে একটি রিসেট লিংক পাঠায়",
        "ইউজার লিংকে ক্লিক করে একটি নতুন পাসওয়ার্ড লেখে",
        "সিস্টেম নতুন পাসওয়ার্ড সংরক্ষণ করে নিশ্চিতকরণ বার্তা দেখায়",
    ],
    alternative_flows={
        "ইমেইল সিস্টেমে খুঁজে পাওয়া যায়নি": [
            "সিস্টেম 'এই ইমেইলে কোনো অ্যাকাউন্ট নেই' বার্তা দেখায়",
            "ইউজারকে আবার সঠিক ইমেইল লেখার সুযোগ দেওয়া হয়",
        ],
    },
    postconditions=[
        "ইউজারের পাসওয়ার্ড আপডেট হয়েছে",
        "ইউজার নতুন পাসওয়ার্ড দিয়ে সফলভাবে লগইন করতে পারে",
    ],
)

print_use_case(reset_password)

    
লক্ষ্য করুন alternative_flows একটি dict — কারণ একটি ইউজ কেসের একাধিক আলাদা অল্টারনেটিভ সিনারিও থাকতে পারে (এখানে শুধু একটি দেখানো হয়েছে), প্রতিটির নিজস্ব নাম ও নিজস্ব ধাপের তালিকা। বাস্তব সিস্টেমে "পাসওয়ার্ড রিসেট"-এর আরও অল্টারনেটিভ ফ্লো থাকতে পারে — যেমন "রিসেট লিংকের মেয়াদ শেষ হয়ে গেছে" — মূল আইডিয়া একই থাকে।
মূল কথা · Key takeaway

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

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

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

প্র ০১ একটি ইউজ কেসে "অল্টারনেটিভ ফ্লো" না লিখলে কী সমস্যা হতে পারে?

অল্টারনেটিভ ফ্লো ছাড়া একটি ইউজ কেস শুধু "সব ঠিক থাকলে কী হয়" তা বর্ণনা করে, কিন্তু বাস্তব সিস্টেম প্রায়ই অপ্রত্যাশিত পরিস্থিতির মুখোমুখি হয় — ভুল ইনপুট, না-পাওয়া ডেটা, নেটওয়ার্ক ব্যর্থতা। এই এরর কেসগুলো আগে থেকে চিন্তা না করলে ডেভেলপাররা নিজেরাই আন্দাজ করে ইমপ্লিমেন্ট করবে, যা অসঙ্গত ও অসম্পূর্ণ আচরণের দিকে নিয়ে যায় — ঠিক L10-এর "রিকোয়ারমেন্ট গ্যাপ" সমস্যার একটি বাস্তব রূপ।

প্র ০২ ইউজ কেস ডায়াগ্রামে একটি ওভাল (ইউজ কেস) কেন কোনো ইমপ্লিমেন্টেশন ডিটেইল (যেমন কোন ডাটাবেস টেবিল ব্যবহার হবে) দেখায় না?

কারণ ইউজ কেস ডায়াগ্রাম একটি রিকোয়ারমেন্ট-লেভেল, ইউজার-কেন্দ্রিক টুল — এটি বর্ণনা করে সিস্টেম "কী করতে পারে" ব্যবহারকারীর দৃষ্টিকোণ থেকে, "কীভাবে ভেতরে বাস্তবায়িত হবে" তা নয়। ইমপ্লিমেন্টেশন ডিটেইল মিশিয়ে দিলে ডায়াগ্রামটি স্টেকহোল্ডারদের জন্য অপ্রয়োজনীয়ভাবে জটিল হয়ে যায় এবং রিকোয়ারমেন্ট ও ডিজাইনের মধ্যে দায়িত্বের সীমারেখা অস্পষ্ট করে দেয় (M4-M6-এ ডিজাইনের ডিটেইল আসবে)।

প্র ০৩ উপরের কোড সেলে alternative_flows কেন একটি list-এর বদলে dict হিসেবে ডিজাইন করা হয়েছে?

কারণ একটি ইউজ কেসের একাধিক ভিন্ন অল্টারনেটিভ সিনারিও থাকতে পারে (যেমন "ইমেইল খুঁজে পাওয়া যায়নি", "রিসেট লিংকের মেয়াদ শেষ"), এবং প্রতিটি সিনারিওর নিজস্ব নাম এবং নিজস্ব ধাপের তালিকা থাকা দরকার। dict ব্যবহার করলে প্রতিটি সিনারিও-নাম (key) সরাসরি তার নিজস্ব ধাপের তালিকার (value) সাথে যুক্ত থাকে — একটি সাধারণ list হলে কোন ধাপগুলো কোন সিনারিওর অংশ তা আলাদা করে ট্র্যাক করতে হতো।

অনুশীলন

  1. চিন্তা করুন: একটি "অনলাইন ফুড ডেলিভারি অ্যাপে অর্ডার প্লেস করা" ইউজ কেসের জন্য অ্যাক্টর, ২টি প্রিকন্ডিশন, এবং ৪-৫টি মেইন ফ্লো ধাপ কী হতে পারে তা লিখুন।

    একটি যুক্তিসঙ্গত উত্তর: অ্যাক্টর — "রেজিস্টার্ড কাস্টমার"। প্রিকন্ডিশন — "কাস্টমার লগইন করা আছে", "কাস্টমারের ঠিকানা সংরক্ষিত আছে"। মেইন ফ্লো — (১) কাস্টমার একটি রেস্তোরাঁ নির্বাচন করে, (২) মেনু থেকে আইটেম কার্টে যোগ করে, (৩) চেকআউটে গিয়ে ডেলিভারি ঠিকানা নিশ্চিত করে, (৪) পেমেন্ট মেথড নির্বাচন করে অর্ডার সাবমিট করে, (৫) সিস্টেম অর্ডার কনফার্মেশন দেখায়। মূল কথা হলো প্রতিটি ধাপ নির্দিষ্ট ও ক্রমানুসারে হওয়া, "কীভাবে" নয় শুধু "কী হচ্ছে" তা বর্ণনা করা।

  2. পরীক্ষা করুন: উপরের কোড সেলে reset_password ইউজ কেসে দ্বিতীয় একটি অল্টারনেটিভ ফ্লো যোগ করুন (যেমন "রিসেট লিংকের মেয়াদ শেষ হয়ে গেছে") এবং Run চেপে দেখুন আউটপুটে সেটি কীভাবে যুক্ত হয়।

    alternative_flows dict-এ একটি নতুন key-value যোগ করলেই যথেষ্ট, যেমন "রিসেট লিংকের মেয়াদ শেষ": ["সিস্টেম 'লিংকের মেয়াদ শেষ' বার্তা দেখায়", "ইউজারকে নতুন লিংক অনুরোধ করার সুযোগ দেওয়া হয়"]। print_use_case() ফাংশনটি dict-এর প্রতিটি key-value জোড়ার উপর লুপ করে, তাই কোনো পরিবর্তন ছাড়াই এটি স্বয়ংক্রিয়ভাবে নতুন অল্টারনেটিভ ফ্লোটিও প্রিন্ট করবে — এটাই একটি ভালো, এক্সটেনসিবল ডেটা স্ট্রাকচার ডিজাইনের সুবিধা।

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

আগের পাঠ
ফাংশনাল বনাম নন-ফাংশনাল রিকোয়ারমেন্ট