১. ভূমিকা
ডার্ট ৩ এই ভাষায় প্যাটার্ন প্রবর্তন করেছে, যা ব্যাকরণের একটি প্রধান নতুন বিভাগ। ডার্ট কোড লেখার এই নতুন পদ্ধতি ছাড়াও, ভাষাটিতে আরও বেশ কিছু উন্নতি করা হয়েছে, যার মধ্যে রয়েছে:
- বিভিন্ন ধরণের ডেটা একত্রিত করার জন্য রেকর্ড ,
- অ্যাক্সেস নিয়ন্ত্রণের জন্য ক্লাস মডিফায়ার , এবং
- নতুন সুইচ এক্সপ্রেশন এবং if-case স্টেটমেন্ট ।
এই বৈশিষ্ট্যগুলো ডার্ট কোড লেখার ক্ষেত্রে আপনার বিকল্পের পরিধি বাড়িয়ে দেয়। এই কোডল্যাবে আপনি শিখবেন, কীভাবে এগুলো ব্যবহার করে আপনার কোডকে আরও সংক্ষিপ্ত, সুবিন্যস্ত এবং নমনীয় করে তোলা যায়।
এই কোডল্যাবটি ধরে নেয় যে ফ্লাটার এবং ডার্ট সম্পর্কে আপনার কিছুটা ধারণা আছে। যদি আপনার মনে হয় যে বিষয়টি আপনার কিছুটা ভুলে গেছেন, তাহলে নিম্নলিখিত রিসোর্সগুলো থেকে বেসিক বিষয়গুলো ঝালিয়ে নিতে পারেন:
আপনি যা তৈরি করবেন
এই কোডল্যাবটি ফ্লাটারে একটি JSON ডকুমেন্ট প্রদর্শন করার জন্য একটি অ্যাপ্লিকেশন তৈরি করে। অ্যাপ্লিকেশনটি একটি বাহ্যিক উৎস থেকে আসা JSON ডেটাকে অনুকরণ করে। JSON-টিতে ডকুমেন্টের ডেটা যেমন পরিবর্তনের তারিখ, শিরোনাম, হেডার এবং প্যারাগ্রাফ থাকে। আপনাকে ডেটাগুলোকে সুন্দরভাবে রেকর্ডে প্যাক করার জন্য কোড লিখতে হবে, যাতে আপনার ফ্লাটার উইজেটগুলোর প্রয়োজন অনুযায়ী সেগুলোকে স্থানান্তর এবং আনপ্যাক করা যায়।
এরপর, যখন মানটি কোনো প্যাটার্নের সাথে মিলে যায়, তখন আপনি সেই প্যাটার্ন ব্যবহার করে উপযুক্ত উইজেটটি তৈরি করেন। এছাড়াও, কীভাবে প্যাটার্ন ব্যবহার করে ডেটাকে লোকাল ভেরিয়েবলে রূপান্তর করা যায়, তাও আপনি দেখতে পাবেন।

আপনি যা শিখবেন
- কীভাবে এমন একটি রেকর্ড তৈরি করা যায় যা বিভিন্ন ধরণের একাধিক মান সংরক্ষণ করে।
- একটি রেকর্ড ব্যবহার করে ফাংশন থেকে একাধিক মান কীভাবে ফেরত দেওয়া যায়
- রেকর্ড এবং অন্যান্য অবজেক্ট থেকে ডেটা মেলানো, যাচাই করা এবং কাঠামোবদ্ধ করার জন্য কীভাবে প্যাটার্ন ব্যবহার করতে হয়।
- নতুন বা বিদ্যমান ভেরিয়েবলে প্যাটার্ন-ম্যাচ করা মান কীভাবে যুক্ত করবেন।
- সুইচ স্টেটমেন্টের নতুন বৈশিষ্ট্য, সুইচ এক্সপ্রেশন এবং if-case স্টেটমেন্ট কীভাবে ব্যবহার করবেন।
- একটি সুইচ স্টেটমেন্ট বা সুইচ এক্সপ্রেশনে প্রতিটি কেস যেন সঠিকভাবে হ্যান্ডেল করা হয়, তা নিশ্চিত করতে এক্সহস্টিভনেস চেকিং- এর সুবিধা কীভাবে নেবেন।
২. আপনার পরিবেশ প্রস্তুত করুন
- ফ্লাটার এসডিকে ইনস্টল করুন।
- ভিজ্যুয়াল স্টুডিও কোড (ভিএস কোড)-এর মতো একটি এডিটর সেট আপ করুন ।
- অন্তত একটি টার্গেট প্ল্যাটফর্মের (iOS, Android, ডেস্কটপ বা ওয়েব ব্রাউজার) জন্য প্ল্যাটফর্ম সেটআপের ধাপগুলো অনুসরণ করুন।
৩. প্রকল্পটি তৈরি করুন
প্যাটার্ন, রেকর্ড এবং অন্যান্য নতুন ফিচারগুলো নিয়ে বিস্তারিত আলোচনার আগে, এক মুহূর্ত সময় নিয়ে একটি ফ্লাটার প্রজেক্ট তৈরি করুন, যেখানে আপনি আপনার সমস্ত কোড লিখবেন।
একটি ফ্লাটার প্রজেক্ট তৈরি করুন
-
patterns_codelabনামের একটি নতুন প্রজেক্ট তৈরি করতেflutter createকমান্ডটি ব্যবহার করুন। `--emptyফ্ল্যাগটিlib/main.dartফাইলে স্ট্যান্ডার্ড কাউন্টার অ্যাপ তৈরি হওয়াকে বাধা দেয়, যা আপনাকে এমনিতেও মুছে ফেলতে হতো।
flutter create --empty patterns_codelab
- এরপর, VS Code ব্যবহার করে
patterns_codelabডিরেক্টরিটি খুলুন।
code patterns_codelab

সর্বনিম্ন SDK সংস্করণ সেট করুন
- আপনার প্রোজেক্টের জন্য এসডিকে ভার্সন সীমাবদ্ধতা এমনভাবে সেট করুন যাতে এটি ডার্ট ৩ বা তার উচ্চতর সংস্করণের উপর নির্ভরশীল হয়।
pubspec.yaml
environment:
sdk: ^3.0.0
৪. প্রকল্পটি স্থাপন করুন
এই ধাপে, আপনি দুটি ডার্ট ফাইল তৈরি বা আপডেট করবেন:
-
main.dartফাইল, যেটিতে অ্যাপটির উইজেটগুলো থাকে, এবং -
data.dartফাইলটি অ্যাপের ডেটা সরবরাহ করে।
পরবর্তী ধাপগুলোতে আপনি এই দুটি ফাইলই পরিবর্তন করতে থাকবেন।
অ্যাপের জন্য ডেটা নির্ধারণ করুন
-
lib/data.dartএকটি নতুন ফাইল তৈরি করুন এবং এতে নিম্নলিখিত কোডটি যোগ করুন:
lib/data.dart
import 'dart:convert';
class Document {
final Map<String, Object?> _json;
Document() : _json = jsonDecode(documentJson);
}
const documentJson = '''
{
"metadata": {
"title": "My Document",
"modified": "2023-05-10"
},
"blocks": [
{
"type": "h1",
"text": "Chapter 1"
},
{
"type": "p",
"text": "Lorem ipsum dolor sit amet, consectetur adipiscing elit."
},
{
"type": "checkbox",
"checked": false,
"text": "Learn Dart 3"
}
]
}
''';
ধরুন, একটি প্রোগ্রাম কোনো বাহ্যিক উৎস, যেমন একটি I/O স্ট্রিম বা HTTP অনুরোধ থেকে ডেটা গ্রহণ করছে। এই কোডল্যাবে, আপনি documentJson ভেরিয়েবলে একটি মাল্টি-লাইন স্ট্রিং ব্যবহার করে আগত JSON ডেটাকে মক করার মাধ্যমে এই আরও বাস্তবসম্মত ব্যবহারের ক্ষেত্রটিকে সরল করবেন।
JSON ডেটা Document ক্লাসে সংজ্ঞায়িত করা হয়েছে। এই কোডল্যাবের পরবর্তী অংশে, আপনি এমন ফাংশন যোগ করবেন যা পার্স করা JSON থেকে ডেটা রিটার্ন করবে। এই ক্লাসটি তার কনস্ট্রাক্টরে _json ফিল্ডটি সংজ্ঞায়িত এবং ইনিশিয়ালাইজ করে।
অ্যাপটি চালান
flutter create কমান্ডটি ডিফল্ট ফ্লাটার ফাইল কাঠামোর অংশ হিসেবে lib/main.dart ফাইলটি তৈরি করে।
- অ্যাপ্লিকেশনটির সূচনা বিন্দু তৈরি করতে,
main.dartফাইলের বিষয়বস্তু নিম্নলিখিত কোড দিয়ে প্রতিস্থাপন করুন:
lib/main.dart
import 'package:flutter/material.dart';
import 'data.dart';
void main() {
runApp(const DocumentApp());
}
class DocumentApp extends StatelessWidget {
const DocumentApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(),
home: DocumentScreen(document: Document()),
);
}
}
class DocumentScreen extends StatelessWidget {
final Document document;
const DocumentScreen({required this.document, super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Title goes here')),
body: const Column(children: [Center(child: Text('Body goes here'))]),
);
}
}
আপনি অ্যাপটিতে নিম্নলিখিত দুটি উইজেট যোগ করেছেন:
-
DocumentAppইউআই থিমিংয়ের জন্য ম্যাটেরিয়াল ডিজাইনের সর্বশেষ সংস্করণটি সেট আপ করে। -
DocumentScreenScaffoldউইজেট ব্যবহার করে পৃষ্ঠার দৃশ্যমান বিন্যাস প্রদান করে।
- সবকিছু ঠিকঠাক চলছে কিনা তা নিশ্চিত করতে, রান অ্যান্ড ডিবাগ- এ ক্লিক করে আপনার হোস্ট মেশিনে অ্যাপটি চালান:

- ডিফল্টরূপে, ফ্লাটার উপলব্ধ টার্গেট প্ল্যাটফর্মটি বেছে নেয়। টার্গেট প্ল্যাটফর্ম পরিবর্তন করতে, স্ট্যাটাস বার থেকে বর্তমান প্ল্যাটফর্মটি নির্বাচন করুন:

আপনি DocumentScreen উইজেটে সংজ্ঞায়িত title এবং body এলিমেন্ট সহ একটি খালি ফ্রেম দেখতে পাবেন:

৫. রেকর্ড তৈরি করুন এবং ফেরত দিন
এই ধাপে, আপনি একটি ফাংশন কল থেকে একাধিক মান ফেরত দেওয়ার জন্য রেকর্ড ব্যবহার করেন। তারপর, মানগুলো অ্যাক্সেস করতে এবং UI-তে তা প্রতিফলিত করতে আপনি DocumentScreen উইজেটে সেই ফাংশনটি কল করেন।
একটি রেকর্ড তৈরি করুন এবং ফেরত দিন
-
data.dartএ, Document ক্লাসেmetadataনামে একটি নতুন গেটার মেথড যোগ করুন যা একটি রেকর্ড রিটার্ন করে:
lib/data.dart
import 'dart:convert';
class Document {
final Map<String, Object?> _json;
Document() : _json = jsonDecode(documentJson);
(String, {DateTime modified}) get metadata { // Add from here...
const title = 'My Document';
final now = DateTime.now();
return (title, modified: now);
} // to here.
}
এই ফাংশনের রিটার্ন টাইপ হলো দুটি ফিল্ডসহ একটি রেকর্ড, যার একটির টাইপ হলো String এবং অন্যটির টাইপ হলো DateTime ।
রিটার্ন স্টেটমেন্টটি দুটি মানকে বন্ধনীর মধ্যে রেখে একটি নতুন রেকর্ড তৈরি করে, (title, modified: now) ।
প্রথম ফিল্ডটি অবস্থানগত ও নামবিহীন, এবং দ্বিতীয় ফিল্ডটির নাম modified ।
রেকর্ড ক্ষেত্রগুলিতে অ্যাক্সেস করুন
-
DocumentScreenউইজেটেরbuildমেথডেmetadatagetter মেথডটি কল করুন, যাতে আপনি আপনার রেকর্ডটি পেতে এবং এর মানগুলো অ্যাক্সেস করতে পারেন:
lib/main.dart
class DocumentScreen extends StatelessWidget {
final Document document;
const DocumentScreen({required this.document, super.key});
@override
Widget build(BuildContext context) {
final metadataRecord = document.metadata; // Add this line.
return Scaffold(
appBar: AppBar(title: Text(metadataRecord.$1)), // Modify this line,
body: Column(
children: [ // And the following line.
Center(child: Text('Last modified ${metadataRecord.modified}')),
],
),
);
}
}
metadata গেটার মেথডটি একটি রেকর্ড রিটার্ন করে, যা metadataRecord নামক লোকাল ভ্যারিয়েবলে অ্যাসাইন করা হয়। একটিমাত্র ফাংশন কল থেকে একাধিক ভ্যালু রিটার্ন করে সেগুলোকে কোনো ভ্যারিয়েবলে অ্যাসাইন করার জন্য রেকর্ড একটি হালকা ও সহজ উপায়।
ওই রেকর্ডে থাকা স্বতন্ত্র ফিল্ডগুলো অ্যাক্সেস করার জন্য, আপনি রেকর্ডের বিল্ট-ইন গেটার সিনট্যাক্স ব্যবহার করতে পারেন।
- পজিশনাল ফিল্ড (যেমন
title, নামবিহীন ফিল্ড) পেতে গেটারটি ব্যবহার করুন।রেকর্ডে। এটি শুধুমাত্র নামবিহীন ফিল্ডগুলো ফেরত দেয়। -
modifiedমতো নামযুক্ত ফিল্ডগুলোর কোনো পজিশনাল গেটার নেই, তাই আপনি সরাসরি এর নামটি ব্যবহার করতে পারেন, যেমনmetadataRecord.modified।
পজিশনাল ফিল্ডের গেটারের নাম নির্ধারণ করতে, $1 থেকে শুরু করুন এবং নামযুক্ত ফিল্ডগুলো এড়িয়ে যান। উদাহরণস্বরূপ:
var record = (named: 'v', 'y', named2: 'x', 'z');
print(record.$1); // prints y
print(record.$2); // prints z
- অ্যাপে JSON ভ্যালুগুলো দেখতে হট রিলোড করুন। আপনি প্রতিবার ফাইল সেভ করার সময় VS Code Dart প্লাগইনটি হট-রিলোড করে।

আপনি দেখতে পাচ্ছেন যে প্রতিটি ফিল্ড প্রকৃতপক্ষে তার টাইপ বজায় রেখেছে।
-
Text()মেথডটি তার প্রথম আর্গুমেন্ট হিসেবে একটি String গ্রহণ করে। -
modifiedফিল্ডটি একটি DateTime, এবং এটিকে স্ট্রিং ইন্টারপোলেশন ব্যবহার করে একটিString-এ রূপান্তর করা হয়।
বিভিন্ন ধরণের ডেটা ফেরত দেওয়ার আরেকটি টাইপ-সেফ উপায় হলো একটি ক্লাস সংজ্ঞায়িত করা, যা আরও বিশদ।
৬. প্যাটার্নের সাহায্যে মেলান এবং কাঠামো ভাঙুন
রেকর্ডস দক্ষতার সাথে বিভিন্ন ধরণের ডেটা সংগ্রহ করতে এবং সহজেই তা আদান-প্রদান করতে পারে। এখন, প্যাটার্ন ব্যবহার করে আপনার কোড উন্নত করুন।
একটি প্যাটার্ন এমন একটি কাঠামোকে উপস্থাপন করে যা এক বা একাধিক মান গ্রহণ করতে পারে, অনেকটা নকশার মতো। প্যাটার্নগুলো প্রকৃত মানের সাথে তুলনা করে নির্ধারণ করা হয় যে সেগুলো মেলে কি না ।
কিছু প্যাটার্ন মিলে গেলে, মিলে যাওয়া ভ্যালুটি থেকে ডেটা বের করে এনে তার ডিস্ট্রাকচারিং করে । ডিস্ট্রাকচারিং আপনাকে একটি অবজেক্ট থেকে ভ্যালু আনপ্যাক করে সেগুলোকে লোকাল ভেরিয়েবলে অ্যাসাইন করতে, অথবা সেগুলোর ওপর আরও ম্যাচিং করার সুযোগ দেয়।
একটি রেকর্ডকে স্থানীয় ভেরিয়েবলে ভেঙে ফেলুন
-
DocumentScreenএরbuildমেথডটিকে রিফ্যাক্টর করেmetadataকল করুন এবং একটি প্যাটার্ন ভেরিয়েবল ডিক্লারেশন ইনিশিয়ালাইজ করতে এটি ব্যবহার করুন:
lib/main.dart
class DocumentScreen extends StatelessWidget {
final Document document;
const DocumentScreen({required this.document, super.key});
@override
Widget build(BuildContext context) {
final (title, modified: modified) = document.metadata; // Modify
return Scaffold(
appBar: AppBar(title: Text(title)), // Modify from here...
body: Column(children: [Center(child: Text('Last modified $modified'))]),
); // To here.
}
}
রেকর্ড প্যাটার্ন (title, modified: modified) -এ দুটি পরিবর্তনশীল প্যাটার্ন রয়েছে যা metadata দ্বারা ফেরত আসা রেকর্ডের ফিল্ডগুলির সাথে মেলে।
- এক্সপ্রেশনটি সাবপ্যাটার্নটির সাথে মিলে যায়, কারণ ফলাফলটি এমন একটি রেকর্ড যাতে দুটি ফিল্ড রয়েছে, যার মধ্যে একটির নাম
modified’। - যেহেতু এগুলি মিলে যায়, তাই ভেরিয়েবল ডিক্লারেশন প্যাটার্নটি এক্সপ্রেশনটিকে ডিস্ট্রাকচার করে, এর মানগুলি অ্যাক্সেস করে এবং সেগুলিকে একই টাইপ ও নামের নতুন লোকাল ভেরিয়েবলের সাথে বাইন্ড করে, যেমন
String titleএবংDateTime modified।
যখন কোনো ফিল্ডের নাম এবং সেটিকে ডেটা প্রদানকারী ভেরিয়েবল একই হয়, তখন তার জন্য একটি সংক্ষিপ্ত পদ্ধতি রয়েছে। DocumentScreen এর build মেথডটিকে নিম্নোক্তভাবে রিফ্যাক্টর করুন।
lib/main.dart
class DocumentScreen extends StatelessWidget {
final Document document;
const DocumentScreen({required this.document, super.key});
@override
Widget build(BuildContext context) {
final (title, :modified) = document.metadata; // Modify
return Scaffold(
appBar: AppBar(title: Text(title)),
body: Column(children: [Center(child: Text('Last modified $modified'))]),
);
}
}
:modified ভেরিয়েবল প্যাটার্নটির সিনট্যাক্স হলো modified: modified এর সংক্ষিপ্ত রূপ। যদি আপনি ভিন্ন নামের একটি নতুন লোকাল ভেরিয়েবল চান, তাহলে এর পরিবর্তে modified: localModified লিখতে পারেন।
- আগের ধাপের মতোই একই ফলাফল দেখতে হট রিলোড করুন। আচরণটি হুবহু একই; আপনি শুধু আপনার কোডটিকে আরও সংক্ষিপ্ত করেছেন।
৭. ডেটা বের করতে প্যাটার্ন ব্যবহার করুন
কিছু নির্দিষ্ট ক্ষেত্রে, প্যাটার্ন শুধু মিল খুঁজে বের করে এবং কোডের কাঠামো ভেঙে দেয় তাই নয়, বরং প্যাটার্নটি মিলছে কি না তার উপর ভিত্তি করে কোডটি কী করবে সে সম্পর্কেও সিদ্ধান্ত নিতে পারে। এগুলোকে খণ্ডনযোগ্য প্যাটার্ন (refutable patterns ) বলা হয়।
গত ধাপে আপনি যে ভেরিয়েবল ডিক্লারেশন প্যাটার্নটি ব্যবহার করেছেন তা একটি অকাট্য প্যাটার্ন : ভ্যালুটি অবশ্যই প্যাটার্নের সাথে মিলতে হবে, নতুবা এটি একটি ত্রুটি এবং ডিস্ট্রাকচারিং ঘটবে না। যেকোনো ভেরিয়েবল ডিক্লারেশন বা অ্যাসাইনমেন্টের কথা ভাবুন; যদি ভেরিয়েবল দুটির টাইপ একই না হয়, তবে আপনি সেটিতে কোনো ভ্যালু অ্যাসাইন করতে পারবেন না।
অপরদিকে, খণ্ডনযোগ্য প্যাটার্নগুলো নিয়ন্ত্রণ প্রবাহের প্রেক্ষাপটে ব্যবহৃত হয়:
- তারা আশা করে যে, তুলনা করার জন্য ব্যবহৃত কিছু মান মিলবে না।
- মানটি মেলে কি না, তার ওপর ভিত্তি করে নিয়ন্ত্রণ প্রবাহকে প্রভাবিত করাই এদের উদ্দেশ্য।
- অমিল হলেও এগুলো কোনো ত্রুটি দেখিয়ে কার্য সম্পাদন থামায় না , বরং সরাসরি পরবর্তী স্টেটমেন্টে চলে যায়।
- তারা এমন ভেরিয়েবলগুলোকে ডিস্ট্রাকচার ও বাইন্ড করতে পারে, যেগুলো শুধুমাত্র মিললেই ব্যবহারযোগ্য ।
প্যাটার্ন ছাড়া JSON মান পড়ুন
এই অংশে, আপনি প্যাটার্ন মেলানো ছাড়াই ডেটা পড়বেন এবং দেখবেন কীভাবে প্যাটার্ন আপনাকে JSON ডেটা নিয়ে কাজ করতে সাহায্য করতে পারে।
-
metadataপূর্ববর্তী সংস্করণটিকে এমন একটি সংস্করণ দিয়ে প্রতিস্থাপন করুন যা_jsonম্যাপ থেকে মানগুলি গ্রহণ করে।metadataএই সংস্করণটি কপি করেDocumentক্লাসে পেস্ট করুন:
lib/data.dart
class Document {
final Map<String, Object?> _json;
Document() : _json = jsonDecode(documentJson);
(String, {DateTime modified}) get metadata {
if (_json.containsKey('metadata')) { // Modify from here...
final metadataJson = _json['metadata'];
if (metadataJson is Map) {
final title = metadataJson['title'] as String;
final localModified = DateTime.parse(
metadataJson['modified'] as String,
);
return (title, modified: localModified);
}
}
throw const FormatException('Unexpected JSON'); // to here.
}
}
এই কোডটি কোনো প্যাটার্ন ব্যবহার না করেই ডেটার গঠন সঠিক কিনা তা যাচাই করে। পরবর্তী ধাপে, আপনি কম কোড ব্যবহার করে একই যাচাইকরণ সম্পন্ন করতে প্যাটার্ন ম্যাচিং ব্যবহার করবেন। অন্য কিছু করার আগে এটি তিনটি পরীক্ষা করে:
- JSON-টিতে আপনার প্রত্যাশিত ডেটা কাঠামো রয়েছে:
if (_json.containsKey('metadata')) - ডেটার ধরণ আপনার প্রত্যাশা অনুযায়ী :
if (metadataJson is Map) - ডেটাটি নাল নয় , যা পূর্ববর্তী যাচাইকরণে পরোক্ষভাবে নিশ্চিত হয়েছে।
ম্যাপ প্যাটার্ন ব্যবহার করে JSON ভ্যালুগুলো পড়ুন
একটি খণ্ডনযোগ্য প্যাটার্নের সাহায্যে, আপনি ম্যাপ প্যাটার্ন ব্যবহার করে যাচাই করতে পারেন যে JSON-টির গঠন প্রত্যাশিত।
-
metadataপূর্ববর্তী সংস্করণটি এই কোড দিয়ে প্রতিস্থাপন করুন:
lib/data.dart
class Document {
final Map<String, Object?> _json;
Document() : _json = jsonDecode(documentJson);
(String, {DateTime modified}) get metadata {
if (_json case { // Modify from here...
'metadata': {'title': String title, 'modified': String localModified},
}) {
return (title, modified: DateTime.parse(localModified));
} else {
throw const FormatException('Unexpected JSON');
} // to here.
}
}
এখানে, আপনি এক নতুন ধরনের if-statement (যা ডার্ট ৩-এ প্রবর্তিত হয়েছিল), if-case দেখতে পাচ্ছেন। case body-টি কেবল তখনই কার্যকর হয়, যখন case pattern-টি _json এর ডেটার সাথে মেলে। এই মিলটি সেই একই চেকগুলো সম্পন্ন করে যা আপনি metadata প্রথম সংস্করণে আগত JSON-কে যাচাই করার জন্য লিখেছিলেন। এই কোডটি নিম্নলিখিত বিষয়গুলো যাচাই করে:
-
_jsonহলো একটি Map টাইপ। -
_jsonএকটিmetadataকী থাকে। -
_jsonনাল নয়। -
_json['metadata']-ও একটি Map টাইপ। -
_json['metadata']-তেtitleএবংmodifiedকী-গুলো রয়েছে। -
titleএবংlocalModifiedহলো স্ট্রিং এবং এগুলো null নয়।
যদি মানটি না মেলে, তাহলে প্যাটার্নটি প্রত্যাখ্যান করে (কার্যক্রম চালিয়ে যেতে অস্বীকার করে) এবং else ক্লজে চলে যায়। যদি মিল সফল হয়, তাহলে প্যাটার্নটি ম্যাপ থেকে title এবং modified এর মানগুলোকে ডিস্ট্রাকচার করে এবং সেগুলোকে নতুন লোকাল ভেরিয়েবলের সাথে বাইন্ড করে।
প্যাটার্নগুলোর সম্পূর্ণ তালিকার জন্য, ফিচার স্পেসিফিকেশনের প্যাটার্নস সেকশনের টেবিলটি দেখুন।
৮. আরও প্যাটার্নের জন্য অ্যাপটি প্রস্তুত করুন।
এখন পর্যন্ত, আপনি JSON ডেটার metadata অংশটি নিয়ে কাজ করেছেন। এই ধাপে, আপনি blocks তালিকার ডেটা পরিচালনা করতে এবং আপনার অ্যাপে তা রেন্ডার করার জন্য আপনার ব্যবসায়িক যুক্তিকে আরও কিছুটা পরিমার্জন করবেন।
{
"metadata": {
// ...
},
"blocks": [
{
"type": "h1",
"text": "Chapter 1"
},
// ...
]
}
ডেটা সংরক্ষণের জন্য একটি ক্লাস তৈরি করুন।
-
data.dartএBlockনামে একটি নতুন ক্লাস যোগ করুন, যেটি JSON ডেটার যেকোনো একটি ব্লকের ডেটা পড়া এবং সংরক্ষণ করতে ব্যবহৃত হয়।
lib/data.dart
class Block {
final String type;
final String text;
Block(this.type, this.text);
factory Block.fromJson(Map<String, dynamic> json) {
if (json case {'type': final type, 'text': final text}) {
return Block(type, text);
} else {
throw const FormatException('Unexpected JSON format');
}
}
}
fromJson() ফ্যাক্টরি কনস্ট্রাক্টরটি ম্যাপ প্যাটার্নের সাথে সেই একই if-case ব্যবহার করে যা আপনি আগে দেখেছেন।
আপনি দেখবেন যে JSON ডেটাটি প্রত্যাশিত প্যাটার্নের মতোই দেখাচ্ছে, যদিও এতে checked নামে একটি অতিরিক্ত তথ্য রয়েছে যা প্যাটার্নটিতে নেই। এর কারণ হলো, যখন আপনি এই ধরনের প্যাটার্ন (যাকে 'ম্যাপ প্যাটার্ন' বলা হয়) ব্যবহার করেন, তখন এগুলো শুধুমাত্র প্যাটার্নে আপনার সংজ্ঞায়িত করা নির্দিষ্ট বিষয়গুলোকেই গুরুত্ব দেয় এবং ডেটার অন্য সবকিছুকে উপেক্ষা করে।
ব্লক অবজেক্টের একটি তালিকা ফেরত দিন
- এরপর,
Documentক্লাসেgetBlocks()নামে একটি নতুন ফাংশন যোগ করুন।getBlocks()ফাংশনটি JSON ডেটাকে পার্স করেBlockক্লাসের ইনস্ট্যান্স তৈরি করে এবং আপনার UI-তে রেন্ডার করার জন্য ব্লকগুলোর একটি তালিকা রিটার্ন করে।
lib/data.dart
class Document {
final Map<String, Object?> _json;
Document() : _json = jsonDecode(documentJson);
(String, {DateTime modified}) get metadata {
if (_json case {
'metadata': {'title': String title, 'modified': String localModified},
}) {
return (title, modified: DateTime.parse(localModified));
} else {
throw const FormatException('Unexpected JSON');
}
}
List<Block> getBlocks() { // Add from here...
if (_json case {'blocks': List blocksJson}) {
return [for (final blockJson in blocksJson) Block.fromJson(blockJson)];
} else {
throw const FormatException('Unexpected JSON format');
}
} // to here.
}
getBlocks() ফাংশনটি Block অবজেক্টের একটি লিস্ট রিটার্ন করে, যা আপনি পরবর্তীতে UI তৈরি করতে ব্যবহার করেন। একটি পরিচিত if-case স্টেটমেন্ট ভ্যালিডেশন সম্পন্ন করে এবং blocks মেটাডেটার ভ্যালুকে blocksJson নামের একটি নতুন List কাস্ট করে (প্যাটার্ন ছাড়া কাস্ট করার জন্য আপনার toList() মেথডটির প্রয়োজন হবে)।
নতুন তালিকাটিকে Block অবজেক্ট দিয়ে পূরণ করার জন্য লিস্ট লিটারেলটিতে একটি কালেকশন রয়েছে।
এই অংশে এমন কোনো প্যাটার্ন-সম্পর্কিত বৈশিষ্ট্য উপস্থাপন করা হয়নি যা আপনি এই কোডল্যাবে ইতিমধ্যে চেষ্টা করেননি। পরবর্তী ধাপে, আপনি আপনার UI-তে তালিকার আইটেমগুলো রেন্ডার করার জন্য প্রস্তুতি নেবেন।
৯. ডকুমেন্টটি প্রদর্শন করতে প্যাটার্ন ব্যবহার করুন।
আপনি এখন if-case স্টেটমেন্ট এবং খণ্ডনযোগ্য প্যাটার্ন ব্যবহার করে আপনার JSON ডেটাকে সফলভাবে ভেঙে আবার নতুন করে সাজাতে পারেন। কিন্তু প্যাটার্নের সাথে আসা কন্ট্রোল ফ্লো স্ট্রাকচারের উন্নতিগুলোর মধ্যে if-case শুধুমাত্র একটি। এখন, আপনি আপনার খণ্ডনযোগ্য প্যাটার্নের জ্ঞানকে switch স্টেটমেন্টে প্রয়োগ করবেন।
সুইচ স্টেটমেন্টের সাহায্যে প্যাটার্ন ব্যবহার করে রেন্ডার করা বিষয়বস্তু নিয়ন্ত্রণ করুন।
-
main.dartএBlockWidgetনামে একটি নতুন উইজেট তৈরি করুন, যা প্রতিটি ব্লকেরtypeফিল্ডের উপর ভিত্তি করে তার স্টাইলিং নির্ধারণ করবে।
lib/main.dart
class BlockWidget extends StatelessWidget {
final Block block;
const BlockWidget({required this.block, super.key});
@override
Widget build(BuildContext context) {
TextStyle? textStyle;
switch (block.type) {
case 'h1':
textStyle = Theme.of(context).textTheme.displayMedium;
case 'p' || 'checkbox':
textStyle = Theme.of(context).textTheme.bodyMedium;
case _:
textStyle = Theme.of(context).textTheme.bodySmall;
}
return Container(
margin: const EdgeInsets.all(8),
child: Text(block.text, style: textStyle),
);
}
}
build মেথডের switch স্টেটমেন্টটি block অবজেক্টের type ফিল্ডের উপর ভিত্তি করে সুইচ করে।
- প্রথম কেস স্টেটমেন্টটিতে একটি ধ্রুবক স্ট্রিং প্যাটার্ন ব্যবহার করা হয়েছে। যদি
block.typeধ্রুবক মানh1এর সমান হয়, তবে প্যাটার্নটি ম্যাচ করে। - দ্বিতীয় কেস স্টেটমেন্টটিতে একটি লজিক্যাল-অর প্যাটার্ন ব্যবহার করা হয়েছে, যার সাবপ্যাটার্ন হিসেবে দুটি কনস্ট্যান্ট স্ট্রিং প্যাটার্ন রয়েছে। প্যাটার্নটি তখনই ম্যাচ করে, যখন
block.typeসাবপ্যাটার্নpঅথবাcheckboxএর যেকোনো একটির সাথে মেলে।
- শেষ ক্ষেত্রটি হলো একটি ওয়াইল্ডকার্ড প্যাটার্ন ,
_। সুইচ কেসের মধ্যে থাকা ওয়াইল্ডকার্ড অন্য সবকিছুর সাথে মিলে যায়। এগুলোর আচরণdefaultক্লজের মতোই, যা সুইচ স্টেটমেন্টেও ব্যবহার করা যায় (তবে এগুলো একটু বেশি বিশদ)।
যেখানেই প্যাটার্ন ব্যবহারের অনুমতি আছে, সেখানেই ওয়াইল্ডকার্ড প্যাটার্ন ব্যবহার করা যেতে পারে—উদাহরণস্বরূপ, ভেরিয়েবল ঘোষণার প্যাটার্নে: var (title, _) = document.metadata;
এই প্রসঙ্গে, ওয়াইল্ডকার্ড কোনো ভেরিয়েবলকে আবদ্ধ করে না। এটি দ্বিতীয় ফিল্ডটিকে বাতিল করে দেয়।
পরবর্তী অংশে, Block অবজেক্টগুলো প্রদর্শন করার পর আপনি আরও কিছু সুইচ বৈশিষ্ট্য সম্পর্কে জানতে পারবেন।
ডকুমেন্টের বিষয়বস্তু প্রদর্শন করুন
DocumentScreen উইজেটের build মেথডে getBlocks() কল করে Block অবজেক্টগুলোর তালিকা সম্বলিত একটি লোকাল ভ্যারিয়েবল তৈরি করুন।
-
DocumentationScreenএ বিদ্যমানbuildপদ্ধতিটি এই সংস্করণ দিয়ে প্রতিস্থাপন করুন:
lib/main.dart
class DocumentScreen extends StatelessWidget {
final Document document;
const DocumentScreen({required this.document, super.key});
@override
Widget build(BuildContext context) {
final (title, :modified) = document.metadata;
final blocks = document.getBlocks(); // Add this line
return Scaffold(
appBar: AppBar(title: Text(title)),
body: Column(
children: [
Text('Last modified: $modified'), // Modify from here
Expanded(
child: ListView.builder(
itemCount: blocks.length,
itemBuilder: (context, index) {
return BlockWidget(block: blocks[index]);
},
),
), // to here.
],
),
);
}
}
BlockWidget(block: blocks[index]) লাইনটি ` getBlocks() মেথড থেকে ফেরত আসা ব্লকের তালিকার প্রতিটি আইটেমের জন্য একটি BlockWidget উইজেট তৈরি করে।
- অ্যাপ্লিকেশনটি চালান, তাহলে আপনি স্ক্রিনে ব্লকগুলো দেখতে পাবেন:

১০. সুইচ এক্সপ্রেশন ব্যবহার করুন
প্যাটার্ন switch এবং case এ অনেক ক্ষমতা যোগ করে। এগুলিকে আরও বেশি জায়গায় ব্যবহারযোগ্য করার জন্য, ডার্টে switch এক্সপ্রেশন রয়েছে। একাধিক case-এর মাধ্যমে সরাসরি কোনো ভেরিয়েবল অ্যাসাইনমেন্ট বা return স্টেটমেন্টে একটি মান প্রদান করা যায়।
সুইচ স্টেটমেন্টকে সুইচ এক্সপ্রেশনে রূপান্তর করুন
ডার্ট অ্যানালাইজার আপনাকে আপনার কোডে পরিবর্তন আনতে সহায়তা করে।
- আপনার কার্সারটি পূর্ববর্তী অংশের সুইচ স্টেটমেন্টটিতে নিয়ে যান।
- উপলব্ধ সহায়তাগুলো দেখতে লাইটবাল্বটিতে ক্লিক করুন।
- সুইচ এক্সপ্রেশন অ্যাসিস্টে রূপান্তর নির্বাচন করুন।

এই কোডটির নতুন সংস্করণটি দেখতে এইরকম:
lib/main.dart
class BlockWidget extends StatelessWidget {
final Block block;
const BlockWidget({required this.block, super.key});
@override
Widget build(BuildContext context) {
TextStyle? textStyle; // Modify from here
textStyle = switch (block.type) {
'h1' => Theme.of(context).textTheme.displayMedium,
'p' || 'checkbox' => Theme.of(context).textTheme.bodyMedium,
_ => Theme.of(context).textTheme.bodySmall,
}; // to here.
return Container(
margin: const EdgeInsets.all(8),
child: Text(block.text, style: textStyle),
);
}
}
একটি সুইচ এক্সপ্রেশন দেখতে সুইচ স্টেটমেন্টের মতোই, কিন্তু এটি case কীওয়ার্ডটি বাদ দেয় এবং প্যাটার্নটিকে কেস বডি থেকে আলাদা করতে => ব্যবহার করে। সুইচ স্টেটমেন্টের থেকে ভিন্ন, সুইচ এক্সপ্রেশন একটি ভ্যালু রিটার্ন করে এবং যেকোনো এক্সপ্রেশনের মতো এটিও ব্যবহার করা যায়।
১১. বস্তুর প্যাটার্ন ব্যবহার করুন
ডার্ট একটি অবজেক্ট-ওরিয়েন্টেড ভাষা, তাই প্যাটার্নগুলো সমস্ত অবজেক্টের ক্ষেত্রে প্রযোজ্য। এই ধাপে, আপনি একটি অবজেক্ট প্যাটার্ন চালু করবেন এবং আপনার UI-এর তারিখ রেন্ডারিং লজিক উন্নত করার জন্য অবজেক্ট প্রোপার্টিগুলোর ডিস্ট্রাকচারিং করবেন।
অবজেক্ট প্যাটার্ন থেকে বৈশিষ্ট্য বের করুন
এই অংশে, আপনি প্যাটার্ন ব্যবহার করে সর্বশেষ পরিবর্তনের তারিখ প্রদর্শনের পদ্ধতি উন্নত করবেন।
-
main.dartএformatDateমেথডটি যোগ করুন:
lib/main.dart
String formatDate(DateTime dateTime) {
final today = DateTime.now();
final difference = dateTime.difference(today);
return switch (difference) {
Duration(inDays: 0) => 'today',
Duration(inDays: 1) => 'tomorrow',
Duration(inDays: -1) => 'yesterday',
Duration(inDays: final days, isNegative: true) => '${days.abs()} days ago',
Duration(inDays: final days) => '$days days from now',
};
}
এই মেথডটি একটি সুইচ এক্সপ্রেশন রিটার্ন করে যা ভ্যালু difference (একটি Duration অবজেক্ট)-এর উপর ভিত্তি করে সুইচ করে। এটি today এবং JSON ডেটা থেকে প্রাপ্ত modified ভ্যালুর মধ্যবর্তী সময়কালকে নির্দেশ করে।
সুইচ এক্সপ্রেশনের প্রতিটি ক্ষেত্রে একটি অবজেক্ট প্যাটার্ন ব্যবহার করা হচ্ছে, যা অবজেক্টের inDays এবং isNegative প্রোপার্টিগুলোর গেটার কল করার মাধ্যমে ম্যাচ করে। সিনট্যাক্স দেখে মনে হতে পারে এটি একটি Duration অবজেক্ট তৈরি করছে, কিন্তু আসলে এটি difference অবজেক্টের ফিল্ডগুলো অ্যাক্সেস করছে।
প্রথম তিনটি ক্ষেত্রে, অবজেক্ট প্রপার্টি inDays মেলানোর জন্য এবং সংশ্লিষ্ট স্ট্রিংটি ফেরত দেওয়ার জন্য ধ্রুবক সাবপ্যাটার্ন 0 , 1 এবং -1 ব্যবহার করা হয়।
শেষের দুটি ক্ষেত্রে আজ, গতকাল এবং আগামীকালের বাইরের সময়কাল বিবেচনা করা হয়:
- যদি
isNegativeপ্রপার্টিটিtrueবুলিয়ান কনস্ট্যান্ট প্যাটার্নের সাথে মেলে, যার অর্থ পরিবর্তনের তারিখটি অতীতের, তাহলে এটি `days ago` প্রদর্শন করে। - যদি সেই ক্ষেত্রে পার্থক্যটি ধরা না পড়ে, তাহলে সময়কাল অবশ্যই একটি ধনাত্মক দিনসংখ্যা হতে হবে (
isNegative: falseদিয়ে স্পষ্টভাবে যাচাই করার প্রয়োজন নেই), ফলে পরিবর্তনের তারিখটি ভবিষ্যতে হবে এবং এখন থেকে দিন সংখ্যা প্রদর্শন করবে।
সপ্তাহের জন্য ফরম্যাটিং লজিক যোগ করুন
- আপনার ফরম্যাটিং ফাংশনে ৭ দিনের বেশি সময়কাল শনাক্ত করার জন্য দুটি নতুন কেস যোগ করুন, যাতে UI সেগুলোকে সপ্তাহ হিসেবে প্রদর্শন করতে পারে।
lib/main.dart
String formatDate(DateTime dateTime) {
final today = DateTime.now();
final difference = dateTime.difference(today);
return switch (difference) {
Duration(inDays: 0) => 'today',
Duration(inDays: 1) => 'tomorrow',
Duration(inDays: -1) => 'yesterday',
Duration(inDays: final days) when days > 7 => '${days ~/ 7} weeks from now', // Add from here
Duration(inDays: final days) when days < -7 =>
'${days.abs() ~/ 7} weeks ago', // to here.
Duration(inDays: final days, isNegative: true) => '${days.abs()} days ago',
Duration(inDays: final days) => '$days days from now',
};
}
এই কোডটিতে গার্ড ক্লজ অন্তর্ভুক্ত করা হয়েছে:
- গার্ড ক্লজে কেস প্যাটার্নের পরে
whenকীওয়ার্ডটি ব্যবহৃত হয়। - এগুলো if-case, switch statement, এবং switch expression-এ ব্যবহার করা যায়।
- কোনো প্যাটার্ন মিলে যাওয়ার পরেই কেবল তাতে শর্ত যোগ করা হয়।
- যদি গার্ড ক্লজটির মান ফলস হয়, তাহলে সম্পূর্ণ প্যাটার্নটি খণ্ডন করা হয় এবং এক্সিকিউশন পরবর্তী কেসে চলে যায়।
UI-তে নতুন ফরম্যাট করা তারিখটি যোগ করুন।
- অবশেষে,
formatDateফাংশনটি ব্যবহার করার জন্যDocumentScreenএর `buildমেথডটি আপডেট করুন:
lib/main.dart
class DocumentScreen extends StatelessWidget {
final Document document;
const DocumentScreen({required this.document, super.key});
@override
Widget build(BuildContext context) {
final (title, :modified) = document.metadata;
final formattedModifiedDate = formatDate(modified); // Add this line
final blocks = document.getBlocks();
return Scaffold(
appBar: AppBar(title: Text(title)),
body: Column(
children: [
Text('Last modified: $formattedModifiedDate'), // Modify this line
Expanded(
child: ListView.builder(
itemCount: blocks.length,
itemBuilder: (context, index) {
return BlockWidget(block: blocks[index]);
},
),
),
],
),
);
}
}
- আপনার অ্যাপের পরিবর্তনগুলো দেখতে হট রিলোড করুন:

১২. সম্পূর্ণ পরিবর্তনের জন্য একটি ক্লাস সিল করুন।
লক্ষ্য করুন যে আপনি শেষ সুইচটির শেষে কোনো ওয়াইল্ডকার্ড বা ডিফল্ট কেস ব্যবহার করেননি। যদিও এমন মানগুলোর জন্য সবসময় একটি কেস অন্তর্ভুক্ত করা ভালো অভ্যাস যেগুলো বাদ পড়ে যেতে পারে, এই ধরনের একটি সাধারণ উদাহরণের ক্ষেত্রে এটি ঠিক আছে, কারণ আপনি জানেন যে আপনার সংজ্ঞায়িত কেসগুলো inDays সম্ভাব্য সমস্ত মানকেই বিবেচনা করে।
যখন একটি সুইচের প্রতিটি কেস হ্যান্ডেল করা হয়, তখন তাকে এক্সহস্টিভ সুইচ বলা হয়। উদাহরণস্বরূপ, একটি bool টাইপের উপর সুইচিং এক্সহস্টিভ হয় যখন এর true এবং false জন্য কেস থাকে। একটি enum টাইপের উপর সুইচিংও এক্সহস্টিভ হয় যখন এনামের প্রতিটি ভ্যালুর জন্য কেস থাকে, কারণ এনাম একটি নির্দিষ্ট সংখ্যক ধ্রুবক মানকে প্রতিনিধিত্ব করে।
ডার্ট ৩ নতুন ক্লাস মডিফায়ার ‘ sealed এর মাধ্যমে অবজেক্ট এবং ক্লাস হায়ারার্কি পর্যন্ত সম্পূর্ণতা যাচাই প্রক্রিয়াকে প্রসারিত করেছে। আপনার Block ক্লাসটিকে একটি sealed সুপারক্লাস হিসেবে রিফ্যাক্টর করুন।
সাবক্লাস তৈরি করুন
-
data.dartফাইলে,Blockএক্সটেন্ড করেHeaderBlock,ParagraphBlock, এবংCheckboxBlockএই তিনটি নতুন ক্লাস তৈরি করুন।
lib/data.dart
class HeaderBlock extends Block {
final String text;
HeaderBlock(this.text);
}
class ParagraphBlock extends Block {
final String text;
ParagraphBlock(this.text);
}
class CheckboxBlock extends Block {
final String text;
final bool isChecked;
CheckboxBlock(this.text, this.isChecked);
}
এই ক্লাসগুলোর প্রতিটি মূল JSON-এর বিভিন্ন type ভ্যালু— 'h1' , 'p' , এবং 'checkbox' এর সাথে সঙ্গতিপূর্ণ।
সুপারক্লাস সিল করুন
-
Blockক্লাসটিকেsealedহিসেবে চিহ্নিত করুন। তারপর, if-case-টিকে একটি switch এক্সপ্রেশন হিসেবে রিফ্যাক্টর করুন যা JSON-এ নির্দিষ্ট করাtypeসাথে সঙ্গতিপূর্ণ সাবক্লাসটি রিটার্ন করে:
lib/data.dart
sealed class Block {
Block();
factory Block.fromJson(Map<String, Object?> json) {
return switch (json) {
{'type': 'h1', 'text': String text} => HeaderBlock(text),
{'type': 'p', 'text': String text} => ParagraphBlock(text),
{'type': 'checkbox', 'text': String text, 'checked': bool checked} =>
CheckboxBlock(text, checked),
_ => throw const FormatException('Unexpected JSON format'),
};
}
}
sealed কীওয়ার্ডটি একটি ক্লাস মডিফায়ার, যার অর্থ হলো আপনি শুধুমাত্র একই লাইব্রেরির মধ্যে এই ক্লাসটিকে এক্সটেন্ড বা ইমপ্লিমেন্ট করতে পারবেন। যেহেতু অ্যানালাইজার এই ক্লাসের সাবটাইপগুলো সম্পর্কে জানে, তাই যদি কোনো সুইচ সেগুলোর কোনো একটিকে অন্তর্ভুক্ত করতে ব্যর্থ হয় এবং সম্পূর্ণ না হয়, তবে এটি একটি এরর রিপোর্ট করে।
উইজেটগুলি প্রদর্শন করার জন্য একটি সুইচ এক্সপ্রেশন ব্যবহার করুন।
-
main.dartএরBlockWidgetক্লাসটিকে এমন একটি switch এক্সপ্রেশন দিয়ে আপডেট করুন যা প্রতিটি ক্ষেত্রে অবজেক্ট প্যাটার্ন ব্যবহার করে:
lib/main.dart
class BlockWidget extends StatelessWidget {
final Block block;
const BlockWidget({required this.block, super.key});
@override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.all(8),
child: switch (block) {
HeaderBlock(:final text) => Text(
text,
style: Theme.of(context).textTheme.displayMedium,
),
ParagraphBlock(:final text) => Text(text),
CheckboxBlock(:final text, :final isChecked) => Row(
children: [
Checkbox(value: isChecked, onChanged: (_) {}),
Text(text),
],
),
},
);
}
}
আপনার BlockWidget এর প্রথম সংস্করণে, আপনি একটি TextStyle রিটার্ন করার জন্য Block অবজেক্টের একটি ফিল্ড সুইচ অন করেছিলেন। এখন, আপনি সরাসরি Block অবজেক্টটির একটি ইনস্ট্যান্স সুইচ করবেন এবং এর সাবক্লাসগুলোকে প্রতিনিধিত্বকারী অবজেক্ট প্যাটার্নগুলোর সাথে ম্যাচ করবেন, এবং এই প্রক্রিয়ায় অবজেক্টটির প্রোপার্টিগুলো এক্সট্র্যাক্ট করবেন।
ডার্ট অ্যানালাইজারটি যাচাই করতে পারে যে সুইচ এক্সপ্রেশনে প্রতিটি সাবক্লাস হ্যান্ডেল করা হয়েছে কিনা, কারণ আপনি Block একটি সিলড ক্লাস বানিয়েছেন।
আরও মনে রাখবেন যে, এখানে সুইচ এক্সপ্রেশন ব্যবহার করলে ফলাফলটি সরাসরি child এলিমেন্টে পাঠানো যায়, যার জন্য আগে আলাদা রিটার্ন স্টেটমেন্টের প্রয়োজন হতো না।
- প্রথমবার চেকবক্সের JSON ডেটা রেন্ডার হতে দেখতে হট রিলোড করুন:

১৩. অভিনন্দন
আপনি প্যাটার্ন, রেকর্ড, উন্নত সুইচ ও কেস এবং সিলড ক্লাস নিয়ে সফলভাবে পরীক্ষা-নিরীক্ষা করেছেন। আপনি অনেক তথ্য আলোচনা করেছেন—কিন্তু এই বৈশিষ্ট্যগুলোর কেবল উপরিভাগই ছুঁয়েছেন। প্যাটার্ন সম্পর্কে আরও তথ্যের জন্য, বৈশিষ্ট্য বিবরণী দেখুন।
বিভিন্ন ধরনের প্যাটার্ন, যে ভিন্ন ভিন্ন প্রেক্ষাপটে সেগুলো দেখা যেতে পারে, এবং সাব-প্যাটার্নগুলোর সম্ভাব্য আন্তঃসম্পর্ক আচরণের সম্ভাবনাকে আপাতদৃষ্টিতে অন্তহীন করে তোলে। কিন্তু সেগুলো সহজেই চোখে পড়ে।
প্যাটার্ন ব্যবহার করে ফ্লাটারে কন্টেন্ট প্রদর্শনের নানা উপায় কল্পনা করা যায়। প্যাটার্ন ব্যবহার করে, আপনি নিরাপদে ডেটা এক্সট্র্যাক্ট করতে পারেন এবং মাত্র কয়েকটি কোডের লাইনেই আপনার UI তৈরি করতে পারেন।
এরপর কী?
- ডার্ট ডকুমেন্টেশনের ল্যাঙ্গুয়েজ সেকশনে প্যাটার্ন, রেকর্ড, এনহ্যান্সড সুইচ ও কেস এবং ক্লাস মডিফায়ার সম্পর্কিত ডকুমেন্টেশন দেখে নিন।
রেফারেন্স নথি
সম্পূর্ণ নমুনা কোডটি ধাপে ধাপে flutter/codelabs রিপোজিটরিতে দেখুন।
প্রতিটি নতুন ফিচারের বিস্তারিত বিবরণের জন্য মূল ডিজাইন ডকুমেন্টগুলো দেখুন: