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

দ্রুত Flutter UI কাজ সাধারণত ভালোই শুরু হয়। আপনি লেআউট সামান্য ঠিক করেন, একটি বোতাম যোগ করেন, একটি ফিল্ড সরান, এবং স্ক্রিন দ্রুত ভালো দেখায়। সমস্যা আসে কয়েক রাউন্ড পরে, যখন গতি পরিবর্তনের একটি পাহাড়ে পরিণত হয় যা কেউ রিভিউ করতে চায় না।
টিমগুলো সাধারণত একই ধরনের ব্যর্থতার মুখোমুখি হয়:
একটি বড় কারণ হল "একটি বড় প্রম্পট" পদ্ধতি: পুরো ফিচার বর্ণনা করুন, পুরো স্ক্রিন সেট চাইবেন, এবং বড় আউটপুট গ্রহণ করবেন। সহকারী সাহায্য করতে চায়, কিন্তু এটি একই সময়ে অনেক অংশে ছোঁয়। সেটা পরিবর্তনগুলো বিশৃঙ্খল, রিভিউ করতে কঠিন এবং মার্জ করতে ঝুঁকিপূর্ণ করে তোলে।
পুনরাবৃত্তি করা যায় এমন একটি লুপ এটি ঠিক করে কারণ এটি স্পষ্টতা জোর দেয় এবং বিস্তৃতি সীমিত করে। "ফিচার তৈরি কর" যখন, এর বদলে বারবার এই কাজগুলো করুন: একটি ইউজার স্টোরি নিন, সবচেয়ে ছোট UI স্লাইস জেনারেট করুন যা সেটি প্রমাণ করে, শুধুমাত্র সেই স্লাইসের জন্য প্রয়োজনীয় স্টেট যোগ করুন, তারপর একটি পথের জন্য নেভিগেশন ওয়্যার করুন। প্রতিটি পাস যথেষ্ট ছোট থাকে যাতে রিভিউ করা যায়, এবং ভুল সহজে উল্টানো যায়।
লক্ষ্যটি হল ইউজার স্টোরিকে কনক্রিট স্ক্রিন, স্টেট হ্যান্ডলিং এবং নেভিগেশন ফ্লোতে রূপান্তর করার জন্য একটি ব্যবহারিক ওয়ার্কফ্লো, যেন নিয়ন্ত্রণ না হারায়। ভালোভাবে করলে আপনি মডুলার UI পিস, ছোট ডিফ এবং পরিবর্তনে কম অপ্রত্যাশিততা পাবেন।
ইউজার স্টোরি মানুষদের জন্য লেখা, না যে অ্যাপের উইজেট ট্রি। কিছু জেনারেট করার আগে, স্টোরিকে একটি ছোট UI স্পেসে রূপান্তর করুন যা দৃশ্যমান আচরণ বর্ণনা করে। "Done" হওয়া যাচাইযোগ্য হওয়া উচিত: ব্যবহারকারী কী দেখতে পায়, কী ট্যাপ করে, এবং কী নিশ্চিত করে—না যে ডিজাইনটি "আধুনিক মনে হয়"।
স্কোপ কংক্রিট রাখতে একটি সহজ উপায় হচ্ছে স্টোরিটিকে চারটি বাকেটে ভাঙা:
যদি স্টোরি এখনও অস্পষ্ট মনে হয়, সহজ ভাষায় এই প্রশ্নগুলোর উত্তর দিন:
সূচনায় সীমাবদ্ধতা যোগ করুন কারণ সেগুলো প্রতিটি লেআউট পছন্দকে পরিচালিত করে: থিম বেসিক (রঙ, স্পেসিং, টাইপোগ্রাফি), প্রতিক্রিয়াশীলতা (প্রথমে ফোন পোর্ট্রেট, তারপর ট্যাবলেট), এবং অ্যাক্সেসিবিলিটি ন্যূনতম যেমন ট্যাপ টার্গেট সাইজ, পাঠযোগ্য টেক্সট স্কেলিং এবং আইকনগুলোর অর্থবহ লেবেল।
শেষে, সিদ্ধান্ত নিন কোনগুলো স্থিতিশীল এবং কোনগুলো নমনীয় যাতে আপনি কোডবেস চর্ন না করেন। স্থিতিশীল আইটেমগুলো হল যেগুলো অন্যান্য ফিচার নির্ভর করে, যেমন রুট নাম, ডেটা মডেল এবং বিদ্যমান API। নমনীয় আইটেমগুলো নিরাপদে ইটারেট করা যায়, যেমন লেআউট স্ট্রাকচার, মাইক্রোকপি, এবং নির্দিষ্ট উইজেট কম্পোজিশন।
উদাহরণ: "একজন ব্যবহারকারী হিসেবে, আমি ডিটেইল স্ক্রিন থেকে একটি আইটেম Favorites-এ সেভ করতে পারি।" একটি নির্মাণযোগ্য UI স্পেস হতে পারে:
এটাই যথেষ্ট নির্মাণ, রিভিউ এবং ইটারেট করার জন্য অনুমান ছাড়াই।
ছোট ডিফ মানে ধীর কাজ করা নয়। এগুলো প্রতিটি UI পরিবর্তন রিভিউ করা সহজ, বিপরীত করা সহজ, এবং ভাঙা কঠিন করে। সহজ নিয়ম: প্রতিটি ইটারেশনে একটি স্ক্রিন বা একটি ইন্টারঅ্যাকশনই করুন।
শুরু করার আগে একটি টাইট স্লাইস নির্বাচন করুন। "Orders স্ক্রিনে একটি এম্পটি স্টেট যোগ করুন" ভালো স্লাইস। "সমস্ত Orders ফ্লো রিওয়ার্ক করা" নয়। একটি ডিফ লক্ষ্য করুন যা একটি টিমমেট এক মিনিটে বুঝতে পারবে।
একটি স্থিতিশীল ফোল্ডার স্ট্রাকচারও পরিবর্তনগুলো সীমাবদ্ধ রাখতে সাহায্য করে। একটি সহজ, ফিচার-ফার্স্ট লেআউট আপনাকে উইজেট ও রুটগুলিকে অ্যাপজুড়ে ছড়াতে বাধা দেয়:
lib/
features/
orders/
screens/
widgets/
state/
routes.dart
উইজেটগুলো ছোট ও কম্পোজড রাখুন। যখন একটি উইজেটের স্পষ্ট ইনপুট এবং আউটপুট থাকে, আপনি লেআউট পরিবর্তন করতে পারেন স্টেট ছাড়া, এবং স্টেট পরিবর্তন করতে পারেন UI পুনরায় না লিখে। এমন উইজেট পছন্দ করুন যে সাধারণ মান ও কলব্যাক নেয়, গ্লোবাল স্টেট নয়।
একটি লুপ যা রিভিউযোগ্য থাকে:
একটি কড়া নিয়ম স্থাপন করুন: প্রতিটি পরিবর্তন সহজে রিভার্ট বা আলাদা করা যায়। ইটারেট করার সময় ড্রাই-বাই রিফ্যাক্টর এড়িয়ে চলুন। যদি আপনি অপ্রাসঙ্গিক সমস্যা পান, সেগুলো লিখে রেখে আলাদা কমিটে ঠিক করুন।
আপনার টুল স্ন্যাপশট এবং রোলব্যাক সমর্থন করলে, প্রতিটি স্লাইসকে একটি স্ন্যাপশট পয়েন্ট হিসেবে ব্যবহার করুন। কিছু ভিব-কোডিং প্ল্যাটফর্ম যেমন Koder.ai স্ন্যাপশট ও রোলব্যাক অন্তর্ভুক্ত করে, যা বল্ড UI পরিবর্তন চেষ্টা করার সময় পরীক্ষাকে নিরাপদ করতে পারে।
আরও একটি অভ্যাস যা প্রাথমিক ইটারেশনগুলো শান্ত রাখে: শেয়ার করা উইজেট সম্পাদনা করার চেয়ে নতুন উইজেট যোগ করা পছন্দ করুন। শেয়ার করা কম্পোনেন্টগুলোই ছোট পরিবর্তনগুলোকে বড় ডিফে পরিণত করে।
দ্রুত UI কাজ নিরাপদ থাকে যখন আপনি চিন্তা করা ও টাইপ করা আলাদা রাখেন। কোড জেনারেট করার আগে একটি স্পষ্ট উইজেট ট্রি প্ল্যান নিন।
শুধু একটি উইজেট ট্রি আউটলাইন চাইতে বলুন। আপনি উইজেট নাম, হায়ারার্কি, এবং প্রত্যেক অংশ কী দেখায় তা চান। এখানেই আপনি মিসিং স্টেট, এম্পটি স্ক্রিন এবং অদ্ভুত লেআউট সিদ্ধান্ত ধরতে পারবেন যখন সবকিছু পরিবর্তন করা সস্তা।
একটি কম্পোনেন্ট ব্রেকডাউন চাইুন যার দায়িত্ব স্পষ্ট। প্রতিটি উইজেটকে ফোকাসেড রাখুন: একটি উইজেট হেডার রেন্ডার করবে, আরেকটি লিস্ট, আরেকটি এম্পটি/এরর UI। যদি পরে কিছুএ স্টেট দরকার হবে, এটাকে নোট করুন কিন্তু এখনই ইমপ্লিমেন্ট করবেন না।
স্ক্রিন scaffold এবং stateless উইজেট জেনারেট করুন। একটি সিঙ্গেল স্ক্রিন ফাইল দিয়ে শুরু করুন প্লেসহোল্ডার কন্টেন্ট আর স্পষ্ট TODO-র সঙ্গে। ইনপুটগুলো স্পষ্ট রাখুন (কনস্ট্রাক্টর প্যারাম) যাতে পরে রিয়েল স্টেট প্লাগ করে সহজ হয়।
স্টাইলিং ও লেআউট ডিটেইলস জন্য আলাদা পাস করুন: স্পেসিং, টাইপোগ্রাফি, থিমিং, ও রেস্পনসিভ बिहেভিয়ার। স্টাইলিংকে আলাদা ডিফ হিসেবে ট্রিট করুন যাতে রিভিউ সহজ থাকে।
সীমাবদ্ধতা আগে বলুন যাতে সহকারী এমন UI না উদ্ভ invent করে যা আপনি শিপ করতে পারবেন না:
কনক্রিট উদাহরণ: ইউজার স্টোরি "As a user, I can review my saved items and remove one." একটি উইজেট ট্রি চাইুন যা অ্যাপ বার, আইটেম রো সম্বলিত লিস্ট, ও একটি এম্পটি স্টেট অন্তর্ভুক্ত করে। তারপর SavedItemsScreen, SavedItemTile, EmptySavedItems-এর মত ব্রেকডাউন চাইুন। তারপর স্ট্যাটেলেস স্ক্যাফোল্ড জেনারেট করুন প্লেসহোল্ডার ডেটা দিয়ে, এবং শেষে স্টাইলিং আলাদা পাসে যোগ করুন (ডিভাইডার, প্যাডিং, ও একটি পরিষ্কার রিমুভ বোতাম)।
UI ইটারেশন ভেঙে পড়ে যখন প্রতিটি উইজেট সিদ্ধান্ত নিতে শুরু করে। উইজেট ট্রিট করুন dumb: এটি স্টেট পড়বে এবং রেন্ডার করবে, ব্যবসায়িক নিয়ম ধারণ করবে না।
শুরুতে স্টেটগুলোর নাম সাধারণ ভাষায় রাখুন। বেশিরভাগ ফিচারের বেশি দরকার পড়ে না শুধু "লোডিং" ও "ডোন":
তারপর ইভেন্টগুলো তালিকাভুক্ত করুন যেগুলো স্টেট পরিবর্তন করতে পারে: ট্যাপ, ফর্ম সাবমিট, পুল-টু-রিফ্রেশ, ব্যাক নেভিগেশন, রিট্রাই, এবং "ব্যবহারকারী একটি ফিল্ড সম্পাদনা করেছে"। এগুলো আগে করা থাকলে পরে অনুমান থেকে বাঁচায়।
ফিচারের জন্য একটি স্টেট পদ্ধতি বেছে নিন এবং সেটি মেনে চলুন। লক্ষ্য সর্বশ্রেষ্ঠ প্যাটার্ন নয়—কিন্তু ধারাবাহিক ডিফ।
একটি ছোট স্ক্রিনের জন্য, একটি সহজ কন্ট্রোলার (যেমন ChangeNotifier বা ValueNotifier) যথেষ্ট হতে পারে। লজিক এক জায়গায় রাখুন:
কোড যোগ করার আগে 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 পরিষ্কার থাকে এবং স্টেট কোড ছোট থাকে।
ভাল নেভিগেশন একটি ছোট ম্যাপ হিসেবে শুরু হয়, রুটের চেয়ে নয়। প্রতিটি ইউজার স্টোরির জন্য চারটি মুহূর্ত লিখুন: ব্যবহারকারী কোথা থেকে প্রবেশ করে, সবচেয়ে সম্ভাব্য পরবর্তী ধাপ কী, তারা কীভাবে বাতিল করে, এবং "ব্যাক" কী বোঝায় (পূর্বের স্ক্রিনে ফিরে বা নিরাপদ হোম স্টেটে)।
একটি সহজ রুট ম্যাপ সাধারণত সেই প্রশ্নগুলোর উত্তর দেয় যেগুলো প্রায়ই রিওয়ার্ক সৃষ্টি করে:
তারপর স্ক্রিনগুলোর মধ্যে পাস করা প্যারামিটারগুলো নির্ধারণ করুন। স্পষ্ট হোন: IDs (productId, orderId), ফিল্টার (তারিখ পরিসর, স্ট্যাটাস), এবং ড্রাফট ডেটা (আংশিক ভর্তি ফর্ম)। এটি এড়ালে আপনি গ্লোবাল সিঙ্গলটনগুলোতে কন্টেক্সট লুকিয়ে বা স্ক্রিনগুলি পুনর্নির্মাণ করে সঞ্চয় করতে শুরু করবেন।
ডিপ লিঙ্কগুলো এমনকি যদি প্রথম দিন শিপ না করলেও গুরুত্বপূর্ণ। সিদ্ধান্ত নিন যখন ব্যবহারকারী মাঝপথে ল্যান্ড করে কি হবে: আপনি কি অনুপস্থিত ডেটা লোড করবেন, না কি নিরাপদ এন্ট্রি স্ক্রিনে রিডাইরেক্ট করবেন?
এছাড়াও নির্ধারণ করুন কোন স্ক্রিনগুলো রেজাল্ট রিটার্ন করবে। উদাহরণ: একটি "Select Address" স্ক্রিন একটি addressId রিটার্ন করে, এবং চেকআউট স্ক্রিন সম্পূর্ণ রিফ্রেশ ছাড়া আপডেট হয়। রিটার্ন শেপ ছোট ও টাইপ করা রাখুন যাতে পরিবর্তনগুলো রিভিউতে সহজ থাকে।
কোড করার আগে এজ কেসগুলো আউট করুন: আনসেভড পরিবর্তন (কনফার্ম ডায়ালগ দেখান), অথেন্টিকেশন প্রয়োজন (লগইন পরে পুনরায় চালিয়ে নেওয়া), ও অনুপস্থিত/মুছে ফেলা ডেটা (এরর দেখান এবং পরিষ্কার উপায় দিন)।
আপনি দ্রুত ইটারেট করলে বাস্তব ঝুঁকি হচ্ছে না "ভুল UI", বরং অরিভিউযোগ্য UI। যদি একজন টিমমেট বুঝে না কি পরিবর্তিত হয়েছে, কেন পরিবর্তন হয়েছে, এবং কী স্থিতিশীল আছে, পরবর্তী প্রতিটি ইটারেশন ধীর হয়ে যায়।
একটি নিয়ম: প্রথমে ইন্টারফেসগুলো লক করুন, তারপর ইন্টারনালগুলো চলতে দিন। পাবলিক উইজেট প্রপ্স (ইনপুট), ছোট UI মডেল, এবং রুট আর্গুমেন্ট স্থিতিশীল করুন। একবার সেগুলো নামকরণ ও টাইপ করা হলে, আপনি উইজেট ট্রি পুনরায় সাজাতে পারবেন বাকি অ্যাপ ভেঙে না দিয়ে।
কোড জেনারেট করার আগে একটি ডিফ-ফ্রেন্ডলি প্ল্যান চাইুন। আপনি এমন একটি প্ল্যান চাইবেন যা বলে কোন ফাইল পরিবর্তন হবে এবং কোনগুলো অতোই ছোঁয়া যাবে না। এতে রিভিউ ফোকাসড থাকে এবং আকস্মিক রিফ্যাক্টর এড়ানো যায়।
ডিফ ছোট রাখার প্যাটার্নগুলো:
ধরা যাক ইউজার স্টোরি: "As a shopper, I can edit my shipping address from checkout." প্রথমে রুট আর্গুমেন্ট লক করুন: CheckoutArgs(cartId, shippingAddressId) স্থিতিশীল থাকে। তারপর স্ক্রিনের ভেতর ইটারেট করুন। একবার লেআউট স্থির হলে, সেটিকে AddressForm, AddressSummary, এবং SaveBar এ ভাগ করুন।
স্টেট হ্যান্ডলিং পরিবর্তন হলে (উদাহরণ: ভ্যালিডেশন উইজেট থেকে CheckoutController-এ সরানো), রিভিউ পড়া সহজ থাকবে: UI ফাইলগুলো প্রধানত রেন্ডারিং পরিবর্তন দেখাবে, আর কন্ট্রোলার এক জায়গায় লজিক পরিবর্তন দেখাবে।
দ্রুত এগোনোর দ্রুততম পথ ধীর হওয়া হচ্ছে—সহকারীকে একবারে সবকিছু পরিবর্তন করতে বলা। যদি একটি কমিট লেআউট, স্টেট, এবং নেভিগেশন একসাথে স্পর্শ করে, রিভিউয়াররা বোঝা যাবে না কি ভাঙল, এবং রোলব্যাক মESSy হয়ে যায়।
একটি নিরাপদ অভ্যাস হল প্রতিটি ইন্টারেশনে একটি উদ্দেশ্য রাখা: উইজেট ট্রি গঠন, তারপর স্টেট ওয়্যার, তারপর নেভিগেশন কানেক্ট।
একটি সাধারণ সমস্যা হচ্ছে জেনারেট করা কোড প্রতি স্ক্রিনে ভিন্ন প্যাটার্ন উদ্ভ invent করে। যদি এক পেজ Provider ব্যবহার করে, পরেরটি setState, এবং তৃতীয়টি কাস্টম কন্ট্রোলার যোগ করে, অ্যাপ দ্রুত inconsistent হয়ে যায়। একটি ছোট সেট প্যাটার্ন বেছে নিন এবং মেনে চলুন।
আরেকটি ভুল হচ্ছে build()-এর মধ্যে সরাসরি অ্যাশিনক কাজ রাখা। এটি একটি দ্রুত ডেমোতে ঠিক মনে হতে পারে, কিন্তু পুনরায় বিল্ডে বারবার কল হয়, ফ্লিকর সৃষ্টি করে, এবং ট্র্যাক করা কঠিন বাগ নিয়ে আসে। কলগুলো initState(), একটি ভিউ মডেল, বা ডেডিকেটেড কন্ট্রোলারে সরান এবং build()-কে রেন্ডারিং কেন্দ্রীভূত রাখুন।
নামকরণ একটি চুপচাপ ফাঁদ। কোড কম্পাইল করলেও যদি তা পড়ে Widget1, data2, বা temp মত নাম থাকে, ভবিষ্যৎ রিফ্যাক্টর কষ্টকর হয়। পরিষ্কার নামগুলো সহকারীকে পরবর্তী পরিবর্তনগুলো তৈরি করতেও সাহায্য করে কারণ ইরার্স উদ্দেশ্য স্পষ্ট হয়।
সবচেয়ে খারাপ প্রতিকরণগুলো রোধ করার জন্য গার্ডরেইল:
build()-এ নেটওয়ার্ক বা ডেটাবেস কল নেইএকটি ভিসুয়াল-বাগ ঠিক করার ক্লাসিক উপায় হল আরও Container, Padding, Align, এবং SizedBox যোগ করা যতক্ষণ না সেটি ঠিক দেখায়। কয়েকটি পাস পরে ট্রি অস্পষ্ট হয়ে যায়।
যদি একটি বোতাম মিসঅ্যালাইন করে, প্রথমে র্যাপারগুলো সরিয়ে দেখুন, একটি সিঙ্গেল প্যারেন্ট লেআউট ব্যবহার করুন, বা একটি ছোট উইজেট এক্সট্র্যাক্ট করুন যার নিজস্ব কনস্ট্রেন্ট আছে।
উদাহরণ: একটি চেকআউট স্ক্রিন যেখানে টোটাল প্রাইস লোডিং-এ জাম্প করে। একটি সহকারী হয়ত প্রাইস রোকে "স্থিতিশীল" করতে আরও উইজেট র্যাপ করবে। একটি পরিষ্কার ফিক্স হল লোডিং প্লেসহোল্ডার দিয়ে জায়গা সংরক্ষণ করা এবং রো স্ট্রাকচার অপরিবর্তিত রাখা।
কমিট করার আগে দুই মিনিটের একটি পাস করুন যা ইউজার ভ্যালু যাচাই করে এবং অবাক করা রিগ্রেশনগুলো থেকে রক্ষা করে। লক্ষ্য নিখুঁততা নয়—এই ইটারেশনটিকে রিভিউ করা সহজ, টেস্ট করা সহজ, এবং উল্টানো সহজ করা।
কখনও না পড়ে ইউজার স্টোরি একবার পড়ুন, তারপর চলমান অ্যাপের বিরুদ্ধে (অথবা একটি সহজ উইজেট টেস্টে) এই আইটেমগুলো যাচাই করুন:
একটি বাস্তবতা চেক: যদি আপনি একটি নতুন Order details স্ক্রিন যোগ করেন, আপনাকে (1) তালিকা থেকে এটি খুলতে পারা, (2) একটি লোডিং স্পিনার দেখা, (3) একটি এরর সিমুলেট করা, (4) একটি এম্পটি অর্ডার দেখা, এবং (5) ব্যাক প্রেস করে তালিকায় ফিরে যাওয়া যায় এমন নিশ্চিত করা উচিত।
যদি আপনার ওয়ার্কফ্লো স্ন্যাপশট ও রোলব্যাক সমর্থন করে, বড় UI পরিবর্তনের আগে একটি স্ন্যাপশট নিন। কিছু প্ল্যাটফর্ম যেমন Koder.ai এটি সমর্থন করে, এবং এটি আপনাকে মেইন ব্রাঞ্চ ঝুঁকিতে না রেখে দ্রুত ইটারেট করতে সাহায্য করবে।
ইউজার স্টোরি: "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: উইজেট ট্রি প্লাস লোডিং/এম্পটি/রেডি UIitem_details_screen.dart: UI লেআউট এবং নেভিগেশন প্যারাম গ্রহণ করেfavorites_store.dart: ন্যূনতম স্টেট হোল্ডার এবং আপডেট মেথডapp_routes.dart: রুট ও টাইপ করা নেভিগেশন হেলপারfavorites_screen.dart: স্টেট পড়ে এবং এম্পটি/লিস্ট UI দেখায়যদি কোনো এক ফাইল হয়ে যায় "যেখানে সবকিছু ঘটে", তা ভাগ করে নিন কাজ চালানোর আগে। নাম সহ ছোট ফাইলগুলো পরবর্তী ইটারেশনকে দ্রুত ও নিরাপদ রাখে।
আপনি যদি ওয়ার্কফ্লোটি কেবল তখনই বাস্তবে কাজ করে যখন আপনি "জোনে" থাকেন, তা পর্দা বদলানোর বা একজন টিমমেট ফিচারে স্পর্শ করার সময় ভেঙে যাবে। লুপটিকে অভ্যাসে পরিণত করুন—লিখে রাখুন এবং পরিবর্তনের আকার নিয়ে গার্ডরেইল দিন।
একই টেমপ্লেট ব্যবহার করুন যাতে প্রতিটি ইটারেশন একই ইনপুট থেকে শুরু হয় এবং একই ধরনের আউটপুট দেয়। সংক্ষিপ্ত কিন্তু স্পেসিফিক রাখুন:
এটি সহায়তা করে সহকারীকে মাঝপথে নতুন প্যাটার্ন উদ্ভ invent না করতে।
একটি সংজ্ঞা বেছে নিন যা কোড রিভিউতে সহজে প্রয়োগ করা যায়। উদাহরণস্বরূপ, প্রতিটি ইটারেশনকে সীমিত সংখ্যক ফাইল পরিবর্তন করার নিয়ম দিন, এবং UI রিফ্যাক্টরগুলো বিহেভিয়ার পরিবর্তনের থেকে আলাদা রাখুন।
একটি সহজ নিয়মাবলী:
অন্য চেকপয়েন্ট যোগ করুন যাতে ভুল ধাপে দ্রুত উল্টানো যায়। কমপক্ষে, বড় রিফ্যাক্টরের আগে কমিট ট্যাগ বা লোকাল চেকপয়েন্ট রাখুন। যদি আপনার ওয়ার্কফ্লো স্ন্যাপশট/রোলব্যাক সমর্থন করে, সেগুলো আগ্রাসীভাবে ব্যবহার করুন।
যদি আপনি একটি চ্যাট-ভিত্তিক ওয়ার্কফ্লো চান যা শুরু থেকে শেষ পর্যন্ত Flutter অ্যাপ জেনারেট ও পরিমার্জন করতে পারে, Koder.ai-তে একটি Planning mode আছে যা আপনাকে পরিকল্পনা ও আশা করা ফাইল পরিবর্তন রিভিউ করতে সাহায্য করে প্রয়োগ করার আগে।
Use a small, testable UI spec first. Write 3–6 lines that cover:
Then build only that slice (often one screen + 1–2 widgets).
Convert the story into four buckets:
If you can’t describe the acceptance check quickly, the story is still too fuzzy for a clean UI diff.
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.
Treat it as a hard rule: one intent per iteration.
If a single commit changes layout, state, and routes together, reviewers won’t know what caused a bug, and rollback gets messy.
Keep widgets “dumb": they should render state, not decide business rules.
A practical default:
Avoid putting async calls in —it leads to repeated calls on rebuild.
Define states and transitions in plain English before coding.
Example pattern:
Then list events that move between them (refresh, retry, submit, edit). Code becomes easier to compare against the written rules.
Write a tiny “flow map” for the story:
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.dartThen keep each iteration focused on one feature folder and avoid drive-by refactors elsewhere.
A simple rule: stabilize interfaces, not internals.
Reviewers care most that inputs/outputs stayed stable even if the layout moved around.
Do a two-minute pass:
If your workflow supports it (for example snapshots/rollback), take a snapshot before a bigger layout refactor so you can revert safely.
build()Also lock down what travels between screens (IDs, filters, draft data) so you don’t end up hiding context in globals.