8 মিনিট

Claude Code for Flutter UI iteration: একটি ব্যবহারিক ওয়ার্কফ্লো

Claude Code for Flutter UI iteration: একটি প্রায়োগিক লুপ যা ইউজার স্টোরিকে উইজেট ট্রি, স্টেট এবং নেভিগেশনে রূপান্তর করে—পরিবর্তনগুলো মডুলার ও রিভিউযোগ্য রাখে।

Claude Code for Flutter UI iteration: একটি ব্যবহারিক ওয়ার্কফ্লো

সমস্যা: দ্রুত UI ইটারেশন যেন বিশৃঙ্খলায় না যায়

দ্রুত Flutter UI কাজ সাধারণত ভালোই শুরু হয়। আপনি লেআউট সামান্য ঠিক করেন, একটি বোতাম যোগ করেন, একটি ফিল্ড সরান, এবং স্ক্রিন দ্রুত ভালো দেখায়। সমস্যা আসে কয়েক রাউন্ড পরে, যখন গতি পরিবর্তনের একটি পাহাড়ে পরিণত হয় যা কেউ রিভিউ করতে চায় না।

টিমগুলো সাধারণত একই ধরনের ব্যর্থতার মুখোমুখি হয়:

  • উইজেট ট্রি পরিকল্পনা ছাড়াই বেড়ে যায়, তাই একটি "ছোট" পরিবর্তন অনেক ফাইল ছাড়িয়ে সম্পাদনা বাধ্য করে।
  • স্টেট UI কোডে জুড়ে বসানো হয়, যা রিবিল্ড অনিশ্চিত করে এবং বাগ ট্রেস করা কঠিন করে তোলে।
  • নেভিগেশন লজিক ছড়িয়ে পড়ে (এখানে একটি push, ওখানে একটি pop) যতক্ষণ না প্রবাহগুলো ব্যবহারকারীর বাস্তব চলাফেরার সঙ্গে মিলতে বন্ধ করে।
  • নামকরণ ভেসে যায়, কম্পোনেন্ট দুবার তৈরি হয়, এবং কেউ নিশ্চিত থাকে না কোন উইজেটটি "আসল"।
  • ডিফগুলো বিশাল হয়ে যায়, তাই রিভিউয়াররা ঝুলিয়ে দেখেন, সমস্যা মিস হয়ে যায়, এবং পরে রিগ্রেশন দেখা দেয়।

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

পুনরাবৃত্তি করা যায় এমন একটি লুপ এটি ঠিক করে কারণ এটি স্পষ্টতা জোর দেয় এবং বিস্তৃতি সীমিত করে। "ফিচার তৈরি কর" যখন, এর বদলে বারবার এই কাজগুলো করুন: একটি ইউজার স্টোরি নিন, সবচেয়ে ছোট UI স্লাইস জেনারেট করুন যা সেটি প্রমাণ করে, শুধুমাত্র সেই স্লাইসের জন্য প্রয়োজনীয় স্টেট যোগ করুন, তারপর একটি পথের জন্য নেভিগেশন ওয়্যার করুন। প্রতিটি পাস যথেষ্ট ছোট থাকে যাতে রিভিউ করা যায়, এবং ভুল সহজে উল্টানো যায়।

লক্ষ্যটি হল ইউজার স্টোরিকে কনক্রিট স্ক্রিন, স্টেট হ্যান্ডলিং এবং নেভিগেশন ফ্লোতে রূপান্তর করার জন্য একটি ব্যবহারিক ওয়ার্কফ্লো, যেন নিয়ন্ত্রণ না হারায়। ভালোভাবে করলে আপনি মডুলার UI পিস, ছোট ডিফ এবং পরিবর্তনে কম অপ্রত্যাশিততা পাবেন।

ইউজার স্টোরিকে একটি স্পষ্ট UI স্পেসে পরিণত করুন যা আপনি তৈরি করতে পারেন

ইউজার স্টোরি মানুষদের জন্য লেখা, না যে অ্যাপের উইজেট ট্রি। কিছু জেনারেট করার আগে, স্টোরিকে একটি ছোট UI স্পেসে রূপান্তর করুন যা দৃশ্যমান আচরণ বর্ণনা করে। "Done" হওয়া যাচাইযোগ্য হওয়া উচিত: ব্যবহারকারী কী দেখতে পায়, কী ট্যাপ করে, এবং কী নিশ্চিত করে—না যে ডিজাইনটি "আধুনিক মনে হয়"।

স্কোপ কংক্রিট রাখতে একটি সহজ উপায় হচ্ছে স্টোরিটিকে চারটি বাকেটে ভাঙা:

  • Screens: কী পরিবর্তিত হচ্ছে, কী অপরিবর্তিত আছে।
  • Components: কী নতুন UI অংশ আসে, এবং তারা কোথায় থাকে।
  • States: লোডিং, সাকসেস, এরর, এম্পটি, এবং প্রত্যেকটি কী দেখায়।
  • Events: ট্যাপ, স্বাইপ, পুল-টু-রিফ্রেশ, ব্যাক নেভিগেশন, রিট্রাই।

যদি স্টোরি এখনও অস্পষ্ট মনে হয়, সহজ ভাষায় এই প্রশ্নগুলোর উত্তর দিন:

  • কোন স্ক্রিনগুলো পরিবর্তন হয়, এবং কোনগুলো একই থাকে?
  • কী নতুন কম্পোনেন্ট আসে, এবং কোথায় তা থাকা উচিত?
  • কোন স্টেটগুলো আছে, এবং প্রত্যেকটি কী দেখায়?
  • কোন ইভেন্টগুলো স্টেট পরিবর্তন চালায়?
  • অ্যাপ চালানোর 30 সেকেন্ড পরে কোন এক্সেপ্ট্যান্স চেক আপনি করতে পারবেন?

সূচনায় সীমাবদ্ধতা যোগ করুন কারণ সেগুলো প্রতিটি লেআউট পছন্দকে পরিচালিত করে: থিম বেসিক (রঙ, স্পেসিং, টাইপোগ্রাফি), প্রতিক্রিয়াশীলতা (প্রথমে ফোন পোর্ট্রেট, তারপর ট্যাবলেট), এবং অ্যাক্সেসিবিলিটি ন্যূনতম যেমন ট্যাপ টার্গেট সাইজ, পাঠযোগ্য টেক্সট স্কেলিং এবং আইকনগুলোর অর্থবহ লেবেল।

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

উদাহরণ: "একজন ব্যবহারকারী হিসেবে, আমি ডিটেইল স্ক্রিন থেকে একটি আইটেম Favorites-এ সেভ করতে পারি।" একটি নির্মাণযোগ্য UI স্পেস হতে পারে:

  • ডিটেইল স্ক্রিনে একটি বুকমার্ক আইকন দেখায়।
  • ট্যাপ করলে সেভ স্টেট টগল হয়।
  • সেভ হওয়ার সময় একটি ছোট প্রগ্রেস ইন্ডিকেটর দেখান।
  • ব্যর্থ হলে, একটি ইনলাইন এরর দেখান এবং Retry অ্যাকশন দিন।
  • নেভিগেশন অপরিবর্তিত থাকে (নতুন রুট নেই)।

এটাই যথেষ্ট নির্মাণ, রিভিউ এবং ইটারেট করার জন্য অনুমান ছাড়াই।

ইটারেশন লুপ সাজান যাতে ডিফগুলো ছোট থাকে

ছোট ডিফ মানে ধীর কাজ করা নয়। এগুলো প্রতিটি UI পরিবর্তন রিভিউ করা সহজ, বিপরীত করা সহজ, এবং ভাঙা কঠিন করে। সহজ নিয়ম: প্রতিটি ইটারেশনে একটি স্ক্রিন বা একটি ইন্টারঅ্যাকশনই করুন।

শুরু করার আগে একটি টাইট স্লাইস নির্বাচন করুন। "Orders স্ক্রিনে একটি এম্পটি স্টেট যোগ করুন" ভালো স্লাইস। "সমস্ত Orders ফ্লো রিওয়ার্ক করা" নয়। একটি ডিফ লক্ষ্য করুন যা একটি টিমমেট এক মিনিটে বুঝতে পারবে।

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

lib/
  features/
    orders/
      screens/
      widgets/
      state/
      routes.dart

উইজেটগুলো ছোট ও কম্পোজড রাখুন। যখন একটি উইজেটের স্পষ্ট ইনপুট এবং আউটপুট থাকে, আপনি লেআউট পরিবর্তন করতে পারেন স্টেট ছাড়া, এবং স্টেট পরিবর্তন করতে পারেন UI পুনরায় না লিখে। এমন উইজেট পছন্দ করুন যে সাধারণ মান ও কলব্যাক নেয়, গ্লোবাল স্টেট নয়।

একটি লুপ যা রিভিউযোগ্য থাকে:

  • স্লাইসের জন্য 3 থেকে 6 লাইনের UI স্পেস লিখুন (কি দেখা যাবে, ট্যাপ কি করবে, লোডিং/এরর কেমন দেখাবে)।
  • কেবলমাত্র ন্যূনতম ফাইল জেনারেট বা সম্পাদনা করুন (প্রায়শই একটি স্ক্রিন এবং এক বা দুটি উইজেট)।
  • স্ক্রিন চালান, পরে একটি ক্লিনআপ পাস করুন (নামকরণ, স্পেসিং, অনইউজড প্রপস সরান)।
  • স্লাইস অনুযায়ী কমিট মেসেজ লিখুন।

একটি কড়া নিয়ম স্থাপন করুন: প্রতিটি পরিবর্তন সহজে রিভার্ট বা আলাদা করা যায়। ইটারেট করার সময় ড্রাই-বাই রিফ্যাক্টর এড়িয়ে চলুন। যদি আপনি অপ্রাসঙ্গিক সমস্যা পান, সেগুলো লিখে রেখে আলাদা কমিটে ঠিক করুন।

আপনার টুল স্ন্যাপশট এবং রোলব্যাক সমর্থন করলে, প্রতিটি স্লাইসকে একটি স্ন্যাপশট পয়েন্ট হিসেবে ব্যবহার করুন। কিছু ভিব-কোডিং প্ল্যাটফর্ম যেমন Koder.ai স্ন্যাপশট ও রোলব্যাক অন্তর্ভুক্ত করে, যা বল্ড UI পরিবর্তন চেষ্টা করার সময় পরীক্ষাকে নিরাপদ করতে পারে।

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

স্টেপ-বাই-স্টেপ: একটি ইউজার স্টোরি থেকে উইজেট ট্রি জেনারেট করা

দ্রুত UI কাজ নিরাপদ থাকে যখন আপনি চিন্তা করা ও টাইপ করা আলাদা রাখেন। কোড জেনারেট করার আগে একটি স্পষ্ট উইজেট ট্রি প্ল্যান নিন।

  1. শুধু একটি উইজেট ট্রি আউটলাইন চাইতে বলুন। আপনি উইজেট নাম, হায়ারার্কি, এবং প্রত্যেক অংশ কী দেখায় তা চান। এখানেই আপনি মিসিং স্টেট, এম্পটি স্ক্রিন এবং অদ্ভুত লেআউট সিদ্ধান্ত ধরতে পারবেন যখন সবকিছু পরিবর্তন করা সস্তা।

  2. একটি কম্পোনেন্ট ব্রেকডাউন চাইুন যার দায়িত্ব স্পষ্ট। প্রতিটি উইজেটকে ফোকাসেড রাখুন: একটি উইজেট হেডার রেন্ডার করবে, আরেকটি লিস্ট, আরেকটি এম্পটি/এরর UI। যদি পরে কিছুএ স্টেট দরকার হবে, এটাকে নোট করুন কিন্তু এখনই ইমপ্লিমেন্ট করবেন না।

  3. স্ক্রিন scaffold এবং stateless উইজেট জেনারেট করুন। একটি সিঙ্গেল স্ক্রিন ফাইল দিয়ে শুরু করুন প্লেসহোল্ডার কন্টেন্ট আর স্পষ্ট TODO-র সঙ্গে। ইনপুটগুলো স্পষ্ট রাখুন (কনস্ট্রাক্টর প্যারাম) যাতে পরে রিয়েল স্টেট প্লাগ করে সহজ হয়।

  4. স্টাইলিং ও লেআউট ডিটেইলস জন্য আলাদা পাস করুন: স্পেসিং, টাইপোগ্রাফি, থিমিং, ও রেস্পনসিভ बिहেভিয়ার। স্টাইলিংকে আলাদা ডিফ হিসেবে ট্রিট করুন যাতে রিভিউ সহজ থাকে।

যে প্রম্পট প্যাটার্ন কাজ করে

সীমাবদ্ধতা আগে বলুন যাতে সহকারী এমন UI না উদ্ভ invent করে যা আপনি শিপ করতে পারবেন না:

  • টার্গেট ডিভাইস (শুধু ফোন, ট্যাবলেটও, অরিয়েন্টেশন)
  • ডিজাইন সীমা (Material 3, বিদ্যমান থিম রঙ, স্পেসিং নিয়ম)
  • নেভিগেশন প্রত্যাশা (ব্যাক আচরণ, ডিপ লিঙ্ক থাকা-না থাকলে)
  • গ্রহণযোগ্যতা মাপকাঠি (কি দৃশ্যমান ও ট্যাপযোগ্য হওয়া চাই)
  • বিদ্যমান কোড সীমা (কোন ফাইল/উইজেট অচল রাখতে হবে, নামকরণ কনভেনশন)

কনক্রিট উদাহরণ: ইউজার স্টোরি "As a user, I can review my saved items and remove one." একটি উইজেট ট্রি চাইুন যা অ্যাপ বার, আইটেম রো সম্বলিত লিস্ট, ও একটি এম্পটি স্টেট অন্তর্ভুক্ত করে। তারপর SavedItemsScreen, SavedItemTile, EmptySavedItems-এর মত ব্রেকডাউন চাইুন। তারপর স্ট্যাটেলেস স্ক্যাফোল্ড জেনারেট করুন প্লেসহোল্ডার ডেটা দিয়ে, এবং শেষে স্টাইলিং আলাদা পাসে যোগ করুন (ডিভাইডার, প্যাডিং, ও একটি পরিষ্কার রিমুভ বোতাম)।

স্টেট হ্যান্ডলিং যোগ করুন UI কোড পুরু না করে

Get a working build sooner
চ্যাট থেকে চালু অ্যাপে পৌঁছান—বিল্ড ও হোস্টিং অপশন অন্তর্ভুক্ত।

UI ইটারেশন ভেঙে পড়ে যখন প্রতিটি উইজেট সিদ্ধান্ত নিতে শুরু করে। উইজেট ট্রিট করুন dumb: এটি স্টেট পড়বে এবং রেন্ডার করবে, ব্যবসায়িক নিয়ম ধারণ করবে না।

শুরুতে স্টেটগুলোর নাম সাধারণ ভাষায় রাখুন। বেশিরভাগ ফিচারের বেশি দরকার পড়ে না শুধু "লোডিং" ও "ডোন":

  • Loading (প্রথম লোড বা রিফ্রেশ)
  • Empty (কোন ডেটা নেই)
  • Error (রিকোয়েস্ট ব্যর্থ, পারমিশন নেই)
  • Success (ডেটা প্রস্তুত)
  • Partial input (ফর্ম শুরু হয়েছে, কিন্তু বৈধ নয়)

তারপর ইভেন্টগুলো তালিকাভুক্ত করুন যেগুলো স্টেট পরিবর্তন করতে পারে: ট্যাপ, ফর্ম সাবমিট, পুল-টু-রিফ্রেশ, ব্যাক নেভিগেশন, রিট্রাই, এবং "ব্যবহারকারী একটি ফিল্ড সম্পাদনা করেছে"। এগুলো আগে করা থাকলে পরে অনুমান থেকে বাঁচায়।

উইজেট থেকে স্টেট আলাদা রাখুন

ফিচারের জন্য একটি স্টেট পদ্ধতি বেছে নিন এবং সেটি মেনে চলুন। লক্ষ্য সর্বশ্রেষ্ঠ প্যাটার্ন নয়—কিন্তু ধারাবাহিক ডিফ।

একটি ছোট স্ক্রিনের জন্য, একটি সহজ কন্ট্রোলার (যেমন ChangeNotifier বা ValueNotifier) যথেষ্ট হতে পারে। লজিক এক জায়গায় রাখুন:

  • ইনপুট: UI থেকে ইভেন্ট (submit, refresh, edit)
  • আউটপুট: একটি একক স্টেট অবজেক্ট যা UI রেন্ডার করবে
  • সাইড ইফেক্ট: API কল এবং নেভিগেশন রিকোয়েস্ট

কোড যোগ করার আগে plain English-এ স্টেট ট্রানজিশনগুলো লিখুন। লগইন স্ক্রিনের উদাহরণ:

"When the user taps Sign in: set Loading. If the email is invalid: stay in Partial input and show an inline message. If the password is wrong: set Error with a message and enable Retry. If success: set Success and navigate to Home."

তারপর ঐ বাক্যগুলোর সাথে মিল রেখে ন্যূনতম Dart কোড জেনারেট করুন। রিভিউ সহজ থাকে কারণ আপনি ডিফটি নিয়মগুলোর সাথে তুলনা করতে পারেন।

ইনভ্যালিড ইনপুটের জন্য টেস্টযোগ্য নিয়ম যোগ করুন

ভ্যালিডেশন স্পষ্ট করুন। সিদ্ধান্ত নিন ইনপুট অবৈধ হলে কী হবে:

  • আপনি সাবমিট ব্লক করবেন নাকি অনুমতি দেবেন এবং এরর দেখাবেন?
  • কোন ফিল্ডগুলো কখন এরর দেখায়?
  • ব্যাক নেভিগেশন পার্শিয়াল ইনপুট মুছে ফেলবে নাকি রাখবে?

এসব লেখা থাকলে UI পরিষ্কার থাকে এবং স্টেট কোড ছোট থাকে।

বাস্তব ব্যবহারকারী আচরণ মেলে এমন নেভিগেশন ফ্লো ডিজাইন করুন

ভাল নেভিগেশন একটি ছোট ম্যাপ হিসেবে শুরু হয়, রুটের চেয়ে নয়। প্রতিটি ইউজার স্টোরির জন্য চারটি মুহূর্ত লিখুন: ব্যবহারকারী কোথা থেকে প্রবেশ করে, সবচেয়ে সম্ভাব্য পরবর্তী ধাপ কী, তারা কীভাবে বাতিল করে, এবং "ব্যাক" কী বোঝায় (পূর্বের স্ক্রিনে ফিরে বা নিরাপদ হোম স্টেটে)।

একটি রুট ম্যাপ দিয়ে শুরু করুন, তারপর স্ক্রিনগুলোর মধ্যে কী যাবে তা লক করুন

একটি সহজ রুট ম্যাপ সাধারণত সেই প্রশ্নগুলোর উত্তর দেয় যেগুলো প্রায়ই রিওয়ার্ক সৃষ্টি করে:

  • Entry: কোন স্ক্রিন প্রথম খুলে, এবং কোথা থেকে (ট্যাব, নোটিফিকেশন, ডিপ লিঙ্ক)
  • Next: প্রাথমিক অ্যাকশনের পরে প্রধান ফরোয়ার্ড পথ
  • Cancel: ব্যবহারকারী ফ্লো ছাড়লে তারা কোথায় পৌঁছাবে
  • Back: ব্যাক অনুমোদিত কি না, এবং কী সংরক্ষণ করা উচিত
  • Fallback: প্রয়োজনীয় ডেটা অনুপস্থিত হলে কোথায় নিয়ে যাবে

তারপর স্ক্রিনগুলোর মধ্যে পাস করা প্যারামিটারগুলো নির্ধারণ করুন। স্পষ্ট হোন: IDs (productId, orderId), ফিল্টার (তারিখ পরিসর, স্ট্যাটাস), এবং ড্রাফট ডেটা (আংশিক ভর্তি ফর্ম)। এটি এড়ালে আপনি গ্লোবাল সিঙ্গলটনগুলোতে কন্টেক্সট লুকিয়ে বা স্ক্রিনগুলি পুনর্নির্মাণ করে সঞ্চয় করতে শুরু করবেন।

ডিপ লিঙ্ক ও "রেজাল্ট রিটার্ন" প্যাটার্নের পরিকল্পনা করুন

ডিপ লিঙ্কগুলো এমনকি যদি প্রথম দিন শিপ না করলেও গুরুত্বপূর্ণ। সিদ্ধান্ত নিন যখন ব্যবহারকারী মাঝপথে ল্যান্ড করে কি হবে: আপনি কি অনুপস্থিত ডেটা লোড করবেন, না কি নিরাপদ এন্ট্রি স্ক্রিনে রিডাইরেক্ট করবেন?

এছাড়াও নির্ধারণ করুন কোন স্ক্রিনগুলো রেজাল্ট রিটার্ন করবে। উদাহরণ: একটি "Select Address" স্ক্রিন একটি addressId রিটার্ন করে, এবং চেকআউট স্ক্রিন সম্পূর্ণ রিফ্রেশ ছাড়া আপডেট হয়। রিটার্ন শেপ ছোট ও টাইপ করা রাখুন যাতে পরিবর্তনগুলো রিভিউতে সহজ থাকে।

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

UI পরিবর্তনগুলো রিভিউযোগ্য ও মডুলার রাখুন

আপনি দ্রুত ইটারেট করলে বাস্তব ঝুঁকি হচ্ছে না "ভুল UI", বরং অরিভিউযোগ্য UI। যদি একজন টিমমেট বুঝে না কি পরিবর্তিত হয়েছে, কেন পরিবর্তন হয়েছে, এবং কী স্থিতিশীল আছে, পরবর্তী প্রতিটি ইটারেশন ধীর হয়ে যায়।

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

ছোট, স্থিতিশীল সিম পছন্দ করুন

কোড জেনারেট করার আগে একটি ডিফ-ফ্রেন্ডলি প্ল্যান চাইুন। আপনি এমন একটি প্ল্যান চাইবেন যা বলে কোন ফাইল পরিবর্তন হবে এবং কোনগুলো অতোই ছোঁয়া যাবে না। এতে রিভিউ ফোকাসড থাকে এবং আকস্মিক রিফ্যাক্টর এড়ানো যায়।

ডিফ ছোট রাখার প্যাটার্নগুলো:

  • পাবলিক উইজেটগুলো পাতলা রাখুন: শুধুমাত্র দরকারি ডেটা ও কলব্যাক নিন, সিঙ্গলটনে পৌঁছাবেন না।
  • ব্যবসায়িক নিয়ম উইজেট থেকে আগে বের করে নিন: সিদ্ধান্তগুলো একটি কন্ট্রোলার বা ভিউ মডেলে রাখুন, UI কেবল স্টেট রেন্ডার করুক।
  • একবার একটি UI অংশ প্রতি ঘণ্টায় পরিবর্তন বন্ধ করলে, এটিকে রিইউজেবল উইজেটে এক্সট্র্যাক্ট করুন স্পষ্ট, টাইপ করা API দিয়ে।
  • রুট আর্গুমেন্ট স্পষ্ট রাখুন (একটি আর্গস অবজেক্ট অনেকটি অপশনাল ফিল্ডের চেয়ে পরিস্কার)।
  • আপনার PR বর্ণনায় একটি ছোট চেঞ্জলগ যোগ করুন: কি বদলেছে, কেন, এবং কি টেস্ট করতে হবে।

রিভিউয়াররা পছন্দ করা একটি কংক্রিট উদাহরণ

ধরা যাক ইউজার স্টোরি: "As a shopper, I can edit my shipping address from checkout." প্রথমে রুট আর্গুমেন্ট লক করুন: CheckoutArgs(cartId, shippingAddressId) স্থিতিশীল থাকে। তারপর স্ক্রিনের ভেতর ইটারেট করুন। একবার লেআউট স্থির হলে, সেটিকে AddressForm, AddressSummary, এবং SaveBar এ ভাগ করুন।

স্টেট হ্যান্ডলিং পরিবর্তন হলে (উদাহরণ: ভ্যালিডেশন উইজেট থেকে CheckoutController-এ সরানো), রিভিউ পড়া সহজ থাকবে: UI ফাইলগুলো প্রধানত রেন্ডারিং পরিবর্তন দেখাবে, আর কন্ট্রোলার এক জায়গায় লজিক পরিবর্তন দেখাবে।

AI সহকারী দিয়ে ইটারেট করার সময় সাধারণ ভুল ও ফাঁদ

Ship smaller diffs faster
প্রথমে Flutter স্ক্রিন scaffold জেনারেট করুন, তারপর লেআউট, স্টেট এবং নেভিগেশন ছোট ধাপে ইটারেট করুন।

দ্রুত এগোনোর দ্রুততম পথ ধীর হওয়া হচ্ছে—সহকারীকে একবারে সবকিছু পরিবর্তন করতে বলা। যদি একটি কমিট লেআউট, স্টেট, এবং নেভিগেশন একসাথে স্পর্শ করে, রিভিউয়াররা বোঝা যাবে না কি ভাঙল, এবং রোলব্যাক মESSy হয়ে যায়।

একটি নিরাপদ অভ্যাস হল প্রতিটি ইন্টারেশনে একটি উদ্দেশ্য রাখা: উইজেট ট্রি গঠন, তারপর স্টেট ওয়্যার, তারপর নেভিগেশন কানেক্ট।

যে ভুলগুলো মেসি কোড তৈরি করে

একটি সাধারণ সমস্যা হচ্ছে জেনারেট করা কোড প্রতি স্ক্রিনে ভিন্ন প্যাটার্ন উদ্ভ invent করে। যদি এক পেজ Provider ব্যবহার করে, পরেরটি setState, এবং তৃতীয়টি কাস্টম কন্ট্রোলার যোগ করে, অ্যাপ দ্রুত inconsistent হয়ে যায়। একটি ছোট সেট প্যাটার্ন বেছে নিন এবং মেনে চলুন।

আরেকটি ভুল হচ্ছে build()-এর মধ্যে সরাসরি অ্যাশিনক কাজ রাখা। এটি একটি দ্রুত ডেমোতে ঠিক মনে হতে পারে, কিন্তু পুনরায় বিল্ডে বারবার কল হয়, ফ্লিকর সৃষ্টি করে, এবং ট্র্যাক করা কঠিন বাগ নিয়ে আসে। কলগুলো initState(), একটি ভিউ মডেল, বা ডেডিকেটেড কন্ট্রোলারে সরান এবং build()-কে রেন্ডারিং কেন্দ্রীভূত রাখুন।

নামকরণ একটি চুপচাপ ফাঁদ। কোড কম্পাইল করলেও যদি তা পড়ে Widget1, data2, বা temp মত নাম থাকে, ভবিষ্যৎ রিফ্যাক্টর কষ্টকর হয়। পরিষ্কার নামগুলো সহকারীকে পরবর্তী পরিবর্তনগুলো তৈরি করতেও সাহায্য করে কারণ ইরার্স উদ্দেশ্য স্পষ্ট হয়।

সবচেয়ে খারাপ প্রতিকরণগুলো রোধ করার জন্য গার্ডরেইল:

  • প্রতি ইটারেশনে কেবল একটির পরিবর্তন করুন: লেআউট, স্টেট, বা নেভিগেশন
  • ফিচার জুড়ে একই স্টেট প্যাটার্ন ব্যবহার করুন
  • build()-এ নেটওয়ার্ক বা ডেটাবেস কল নেই
  • প্লেসহোল্ডারগুলো বড় ফিচারে যাচাই করার আগে নাম পরিবর্তন করুন
  • আরও নেস্টিং করার চেয়ে উইজেট এক্সট্র্যাক্ট করা পছন্দ করুন

নেস্টিং ফাঁদ

একটি ভিসুয়াল-বাগ ঠিক করার ক্লাসিক উপায় হল আরও Container, Padding, Align, এবং SizedBox যোগ করা যতক্ষণ না সেটি ঠিক দেখায়। কয়েকটি পাস পরে ট্রি অস্পষ্ট হয়ে যায়।

যদি একটি বোতাম মিসঅ্যালাইন করে, প্রথমে র‍্যাপারগুলো সরিয়ে দেখুন, একটি সিঙ্গেল প্যারেন্ট লেআউট ব্যবহার করুন, বা একটি ছোট উইজেট এক্সট্র্যাক্ট করুন যার নিজস্ব কনস্ট্রেন্ট আছে।

উদাহরণ: একটি চেকআউট স্ক্রিন যেখানে টোটাল প্রাইস লোডিং-এ জাম্প করে। একটি সহকারী হয়ত প্রাইস রোকে "স্থিতিশীল" করতে আরও উইজেট র‍্যাপ করবে। একটি পরিষ্কার ফিক্স হল লোডিং প্লেসহোল্ডার দিয়ে জায়গা সংরক্ষণ করা এবং রো স্ট্রাকচার অপরিবর্তিত রাখা।

দ্রুত চেকলিস্ট: পরবর্তী UI ইটারেশন কমিট করার আগে

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

Commit-ready checklist

কখনও না পড়ে ইউজার স্টোরি একবার পড়ুন, তারপর চলমান অ্যাপের বিরুদ্ধে (অথবা একটি সহজ উইজেট টেস্টে) এই আইটেমগুলো যাচাই করুন:

  • Widget tree matches the story: গ্রহণযোগ্যতামূলক মানদণ্ডের কী উপাদানগুলো আছে এবং দৃশ্যমান। টেক্সট, বোতাম, এবং খালি জায়গা ইচ্ছে করে সাজানো।
  • All states are reachable: লোডিং, এরর, এবং এম্পটি কেবল কোডে স্কেচ না। প্রতিটি ট্রিগার করা যায় (হাইলে একটি ডিবাগ ফ্ল্যাগ দিয়ে) এবং দেখা গ্রহণযোগ্য।
  • Navigation and back behavior make sense: ব্যাক প্রত্যাশিত স্ক্রিনে ফিরে যায়, ডায়ালগ বন্ধ হয় সঠিকভাবে, এবং ডিপ লিঙ্ক (যদি ব্যবহার করা হয়) ভালো জায়গায় ল্যান্ড করে।
  • Diffs stay small and owned: পরিবর্তনগুলো একটি ছোট ফাইল সেটে সীমাবদ্ধ এবং পরিষ্কার অংশীদারিত্ব আছে। কোন ড্রাই-বাই রিফ্যাক্টর নেই।
  • Rollback is clean: যদি আপনি এই কমিট reverট করেন, অন্যান্য স্ক্রিনগুলো এখনও build ও run করে। টেম্পোরারি ফ্ল্যাগ বা প্লেসহোল্ডার অ্যাসেটগুলো যা পরে ভেঙে দিতে পারে সেগুলো সরান।

একটি বাস্তবতা চেক: যদি আপনি একটি নতুন Order details স্ক্রিন যোগ করেন, আপনাকে (1) তালিকা থেকে এটি খুলতে পারা, (2) একটি লোডিং স্পিনার দেখা, (3) একটি এরর সিমুলেট করা, (4) একটি এম্পটি অর্ডার দেখা, এবং (5) ব্যাক প্রেস করে তালিকায় ফিরে যাওয়া যায় এমন নিশ্চিত করা উচিত।

যদি আপনার ওয়ার্কফ্লো স্ন্যাপশট ও রোলব্যাক সমর্থন করে, বড় UI পরিবর্তনের আগে একটি স্ন্যাপশট নিন। কিছু প্ল্যাটফর্ম যেমন Koder.ai এটি সমর্থন করে, এবং এটি আপনাকে মেইন ব্রাঞ্চ ঝুঁকিতে না রেখে দ্রুত ইটারেট করতে সাহায্য করবে।

একটি বাস্তবসম্মত উদাহরণ: ইউজার স্টোরি থেকে স্ক্রিন পর্যন্ত তিন ইটারেশনে

Share a test build easily
আপনি যখন শেয়ার করতে প্রস্তুত, আপনার অ্যাপ একটি কাস্টম ডোমেইনে দিন।

ইউজার স্টোরি: "As a shopper, I can browse items, open a details page, save an item to favorites, and later view my favorites." লক্ষ্য হচ্ছে শব্দ থেকে স্ক্রিন পর্যন্ত তিনটি ছোট, রিভিউযোগ্য ধাপে যাওয়া।

Iteration 1: কেবল ব্রাউজ লিস্ট স্ক্রিনে ফোকাস করুন। প্লেসহোল্ডার ডেটায় রেন্ডার করতে যথেষ্ট একটি উইজেট ট্রি তৈরি করুন: একটি Scaffold সঙ্গে AppBar, একটি ListView প্লেসহোল্ডার রো দিয়ে, এবং লোডিং ও এম্পটি স্টেটের স্পষ্ট UI। স্টেট সহজ রাখুন: loading (একটি CircularProgressIndicator দেখায়), empty (সংক্ষিপ্ত বার্তা ও সম্ভবত Try again বোতাম), এবং ready (লিস্ট দেখায়)।

Iteration 2: ডিটেইলস স্ক্রিন ও নেভিগেশন যোগ করুন। স্পষ্ট রাখুন: onTap একটি রুট পুশ করে এবং একটি ছোট প্যারামি অবজেক্ট পাঠায় (উদাহরণ: item id, title)। ডিটেইলস পেজটি রিড-ওনলি হিসেবে শুরু করুন শিরোনাম, বিবরণ প্লেসহোল্ডার, এবং একটি Favorite অ্যাকশন বোতামসহ। উদ্দেশ্য হলো স্টোরি মিলে যাওয়া: list -> details -> back, অতিরিক্ত ফ্লো ছাড়া।

Iteration 3: ফেভারিটস স্টেট আপডেট ও UI ফিডব্যাক সংযুক্ত করুন। একটি একক সোর্স অফ ট্রুথ (অবশ্যই মেমরি-ভিত্তিক হলেও) যোগ করুন এবং উভয় স্ক্রিনে এটি ওয়্যার করুন। Favorite ট্যাপ করলে আইকন তৎক্ষণাৎ আপডেট হয় এবং একটি ছোট কনফার্মেশন (যেমন একটি SnackBar) দেখান। তারপর একটি Favorites স্ক্রিন যোগ করুন যা একই স্টেট পড়ে এবং এম্পটি/লিস্ট UI হ্যান্ডেল করে।

একটি রিভিউযোগ্য ডিফ সাধারণত এইরকম দেখায়:

  • browse_list_screen.dart: উইজেট ট্রি প্লাস লোডিং/এম্পটি/রেডি UI
  • item_details_screen.dart: UI লেআউট এবং নেভিগেশন প্যারাম গ্রহণ করে
  • favorites_store.dart: ন্যূনতম স্টেট হোল্ডার এবং আপডেট মেথড
  • app_routes.dart: রুট ও টাইপ করা নেভিগেশন হেলপার
  • favorites_screen.dart: স্টেট পড়ে এবং এম্পটি/লিস্ট UI দেখায়

যদি কোনো এক ফাইল হয়ে যায় "যেখানে সবকিছু ঘটে", তা ভাগ করে নিন কাজ চালানোর আগে। নাম সহ ছোট ফাইলগুলো পরবর্তী ইটারেশনকে দ্রুত ও নিরাপদ রাখে।

পরবর্তী ধাপ: ওয়ার্কফ্লোটি ফিচার জুড়ে পুনরাবৃত্তিযোগ্য করুন

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

একটি পুনরাবৃত্তি যোগ্য প্রম্পট টেমপ্লেট তৈরি করুন

একই টেমপ্লেট ব্যবহার করুন যাতে প্রতিটি ইটারেশন একই ইনপুট থেকে শুরু হয় এবং একই ধরনের আউটপুট দেয়। সংক্ষিপ্ত কিন্তু স্পেসিফিক রাখুন:

  • User story + acceptance criteria (কি "ডোন" মানে)
  • UI constraints (ডিজাইন সিস্টেম, স্পেসিং, পুনরায় ব্যবহার করবার উপাদান)
  • State rules (স্টেট কোথায় থাকে, কিসটা লোকাল বনাম শেয়ারড)
  • Navigation rules (রুট, ডিপ লিঙ্ক, ব্যাক আচরণ)
  • Output rules (কোন ফাইল স্পর্শ করতে হবে, কোন টেস্ট আপডেট করতে হবে, ডিফে কি ব্যাখ্যা করতে হবে)

এটি সহায়তা করে সহকারীকে মাঝপথে নতুন প্যাটার্ন উদ্ভ invent না করতে।

"ছোট" কী তা সংজ্ঞায়িত করুন যাতে ডিফগুলো পূর্বানুমানযোগ্য থাকে

একটি সংজ্ঞা বেছে নিন যা কোড রিভিউতে সহজে প্রয়োগ করা যায়। উদাহরণস্বরূপ, প্রতিটি ইটারেশনকে সীমিত সংখ্যক ফাইল পরিবর্তন করার নিয়ম দিন, এবং UI রিফ্যাক্টরগুলো বিহেভিয়ার পরিবর্তনের থেকে আলাদা রাখুন।

একটি সহজ নিয়মাবলী:

  • প্রতিটি ইটারেশনে 3 থেকে 5 ফাইলের বেশি পরিবর্তন নেই
  • প্রতিটি ইটারেশনে একটি নতুন উইজেট বা একটি নেভিগেশন স্টেপ
  • লুপের মাঝখানে নতুন স্টেট ম্যানেজমেন্ট পদ্ধতি আনা যাবে না
  • পরবর্তী ইটারেশনের আগে প্রতিটি পরিবর্তন কম্পাইল ও রান করা লাগবে

অন্য চেকপয়েন্ট যোগ করুন যাতে ভুল ধাপে দ্রুত উল্টানো যায়। কমপক্ষে, বড় রিফ্যাক্টরের আগে কমিট ট্যাগ বা লোকাল চেকপয়েন্ট রাখুন। যদি আপনার ওয়ার্কফ্লো স্ন্যাপশট/রোলব্যাক সমর্থন করে, সেগুলো আগ্রাসীভাবে ব্যবহার করুন।

যদি আপনি একটি চ্যাট-ভিত্তিক ওয়ার্কফ্লো চান যা শুরু থেকে শেষ পর্যন্ত Flutter অ্যাপ জেনারেট ও পরিমার্জন করতে পারে, Koder.ai-তে একটি Planning mode আছে যা আপনাকে পরিকল্পনা ও আশা করা ফাইল পরিবর্তন রিভিউ করতে সাহায্য করে প্রয়োগ করার আগে।

সাধারণ প্রশ্ন

How do I keep a Flutter UI iteration small enough to review?

Use a small, testable UI spec first. Write 3–6 lines that cover:

  • What appears (key widgets/components)
  • What the tap does (one primary interaction)
  • What loading/error/empty look like
  • How you can verify it in 30 seconds

Then build only that slice (often one screen + 1–2 widgets).

What’s the best way to turn a user story into a buildable UI spec?

Convert the story into four buckets:

  • Screens: what changes vs stays the same
  • Components: new widgets and where they live
  • States: loading, empty, error, success (what each shows)
  • Events: taps, back, retry, refresh, form edits

If you can’t describe the acceptance check quickly, the story is still too fuzzy for a clean UI diff.

What should I ask an AI assistant for first: code or structure?

Start by generating only a widget tree outline (names + hierarchy + what each part shows). No code.

Then request a component responsibility breakdown (what each widget owns).

Only after that, generate the stateless scaffold with explicit inputs (values + callbacks), and do styling in a separate pass.

Why does the “one big prompt” approach usually create messy diffs?

Treat it as a hard rule: one intent per iteration.

  • Iteration A: widget tree/layout
  • Iteration B: state wiring
  • Iteration C: navigation wiring

If a single commit changes layout, state, and routes together, reviewers won’t know what caused a bug, and rollback gets messy.

How do I add state without bloating my widget code?

Keep widgets “dumb": they should render state, not decide business rules.

A practical default:

  • Create one controller/view-model that owns events and async work
  • Expose a single state object (loading/empty/error/success)
  • UI reads state and calls callbacks (retry, submit, toggle)

Avoid putting async calls in build()—it leads to repeated calls on rebuild.

Which UI states should I plan for on most screens?

Define states and transitions in plain English before coding.

Example pattern:

  • Loading: show spinner / skeleton
  • Empty: show message + action (like Retry)
  • Error: show inline error + Retry
  • Success: render content

Then list events that move between them (refresh, retry, submit, edit). Code becomes easier to compare against the written rules.

How do I keep navigation flows from getting scattered and inconsistent?

Write a tiny “flow map” for the story:

  • Entry: where the user comes from
  • Next: the main forward step
  • Cancel: where they land if they abandon
  • Back: what back should preserve or discard
  • Fallback: what happens if required data is missing

Also lock down what travels between screens (IDs, filters, draft data) so you don’t end up hiding context in globals.

What folder structure helps keep UI changes contained?

Default to feature-first folders so changes stay contained. For example:

  • lib/features/<feature>/screens/
  • lib/features/<feature>/widgets/
  • lib/features/<feature>/state/
  • lib/features/<feature>/routes.dart

Then keep each iteration focused on one feature folder and avoid drive-by refactors elsewhere.

How do I make my Flutter UI more modular without over-engineering it?

A simple rule: stabilize interfaces, not internals.

  • Keep public widget props small and typed
  • Prefer passing values + callbacks over reading global state
  • Keep route arguments explicit (often a single args object)
  • Extract a widget once it stops changing every hour

Reviewers care most that inputs/outputs stayed stable even if the layout moved around.

What’s a quick pre-commit checklist for a safe UI iteration?

Do a two-minute pass:

  • Can you trigger loading, empty, error, success and do they look acceptable?
  • Does back return where you expect (no weird jumps)?
  • Did you change only a small set of files with clear ownership?
  • Are there any temporary flags/placeholders that could break later?

If your workflow supports it (for example snapshots/rollback), take a snapshot before a bigger layout refactor so you can revert safely.

Related posts