ডার্টের নিদর্শন এবং রেকর্ডগুলিতে ডুব দিন

1. ভূমিকা

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

  • বিভিন্ন ধরনের ডেটা বান্ডিল করার রেকর্ড ,
  • অ্যাক্সেস নিয়ন্ত্রণের জন্য ক্লাস মডিফায়ার , এবং
  • নতুন সুইচ এক্সপ্রেশন এবং যদি-কেস বিবৃতি

এই বৈশিষ্ট্যগুলি ডার্ট কোড লেখার সময় আপনার পছন্দগুলিকে প্রসারিত করে। এই কোডল্যাবে, আপনি আপনার কোডকে আরও কমপ্যাক্ট, স্ট্রিমলাইন এবং নমনীয় করতে কীভাবে সেগুলি ব্যবহার করবেন তা শিখবেন।

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

আপনি কি নির্মাণ করবেন

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

আপনি তারপর উপযুক্ত উইজেট তৈরি করতে প্যাটার্ন ব্যবহার করুন যখন মান সেই প্যাটার্নের সাথে মিলে যায়। আপনি স্থানীয় ভেরিয়েবলগুলিতে ডেটা ধ্বংস করতে নিদর্শনগুলি কীভাবে ব্যবহার করবেন তাও দেখুন।

এই কোডল্যাবে আপনি যে চূড়ান্ত অ্যাপ্লিকেশনটি তৈরি করবেন, একটি শিরোনাম সহ একটি নথি, সর্বশেষ পরিবর্তনের তারিখ, শিরোনাম এবং অনুচ্ছেদ।

আপনি কি শিখবেন

  • কিভাবে একটি রেকর্ড তৈরি করতে হয় যা বিভিন্ন প্রকারের সাথে একাধিক মান সঞ্চয় করে।
  • কিভাবে একটি রেকর্ড ব্যবহার করে একটি ফাংশন থেকে একাধিক মান ফেরত দিতে হয়।
  • রেকর্ড এবং অন্যান্য অবজেক্ট থেকে ডেটা মেলাতে, যাচাই করতে এবং ধ্বংস করতে কীভাবে প্যাটার্ন ব্যবহার করবেন।
  • নতুন বা বিদ্যমান ভেরিয়েবলের সাথে প্যাটার্ন-মিলিত মানগুলিকে কীভাবে আবদ্ধ করবেন।
  • কিভাবে নতুন সুইচ স্টেটমেন্টের ক্ষমতা, সুইচ এক্সপ্রেশন এবং যদি-কেস স্টেটমেন্ট ব্যবহার করতে হয়।
  • প্রতিটি কেস একটি সুইচ স্টেটমেন্ট বা সুইচ এক্সপ্রেশনে পরিচালনা করা হয়েছে তা নিশ্চিত করার জন্য পরিপূর্ণতা যাচাইয়ের সুবিধা কীভাবে নেওয়া যায়।

2. আপনার পরিবেশ সেট আপ করুন

  1. Flutter SDK ইনস্টল করুন।
  2. ভিজ্যুয়াল স্টুডিও কোড (ভিএস কোড) এর মতো একটি সম্পাদক সেট আপ করুন
  3. অন্তত একটি টার্গেট প্ল্যাটফর্মের (iOS, Android, Desktop, বা একটি ওয়েব ব্রাউজার) জন্য প্ল্যাটফর্ম সেটআপ ধাপগুলি দিয়ে যান।

3. প্রকল্প তৈরি করুন

প্যাটার্ন, রেকর্ড এবং অন্যান্য নতুন বৈশিষ্ট্যগুলিতে ডুব দেওয়ার আগে, একটি সাধারণ ফ্লাটার প্রকল্প তৈরি করতে কিছুক্ষণ সময় নিন যার জন্য আপনি আপনার সমস্ত কোড লিখুন৷

একটি ফ্লটার প্রকল্প তৈরি করুন

  1. patterns_codelab নামে একটি নতুন প্রকল্প তৈরি করতে flutter create কমান্ডটি ব্যবহার করুন। --empty পতাকা lib/main.dart ফাইলে স্ট্যান্ডার্ড কাউন্টার অ্যাপ তৈরিতে বাধা দেয়, যা আপনাকে যেভাবেই হোক সরাতে হবে।
flutter create --empty patterns_codelab
  1. তারপর, VS কোড ব্যবহার করে patterns_codelab ডিরেক্টরি খুলুন।
code patterns_codelab

VS কোডের একটি স্ক্রিনশট 'ফ্লাটার ক্রিয়েট' কমান্ড দিয়ে তৈরি করা প্রকল্পটি প্রদর্শন করছে।

ন্যূনতম SDK সংস্করণ সেট করুন

  • আপনার প্রকল্পের জন্য SDK সংস্করণের সীমাবদ্ধতা সেট করুন যাতে Dart 3 বা তার উপরে নির্ভর করে।

pubspec.yaml

environment:
  sdk: ^3.0.0

4. প্রকল্প সেট আপ করুন

এই ধাপে, আপনি দুটি ডার্ট ফাইল তৈরি বা আপডেট করুন:

  • 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 কমান্ড ডিফল্ট Flutter ফাইল কাঠামোর অংশ হিসাবে lib/main.dart ফাইল তৈরি করে।

  1. অ্যাপ্লিকেশনের জন্য একটি সূচনা বিন্দু তৈরি করতে, নিম্নলিখিত কোড দিয়ে 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(useMaterial3: true),
      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 UI থিম করার জন্য মেটেরিয়াল ডিজাইনের সর্বশেষ সংস্করণ সেট আপ করে।
  • DocumentScreen Scaffold উইজেট ব্যবহার করে পৃষ্ঠার ভিজ্যুয়াল লেআউট প্রদান করে।
  1. সবকিছু মসৃণভাবে চলছে তা নিশ্চিত করতে, রান এবং ডিবাগ ক্লিক করে আপনার হোস্ট মেশিনে অ্যাপটি চালান:

'রান এবং ডিবাগ' বোতামের একটি চিত্র, বাম দিকের কার্যকলাপ বারের 'রান এবং ডিবাগ' বিভাগে উপলব্ধ।

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

VS কোডে লক্ষ্য প্ল্যাটফর্ম নির্বাচকের একটি স্ক্রিনশট।

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

এই ধাপে নির্মিত অ্যাপ্লিকেশনটির একটি স্ক্রিনশট।

5. রেকর্ড তৈরি করুন এবং ফেরত দিন

এই ধাপে, আপনি একটি ফাংশন কল থেকে একাধিক মান ফেরত দিতে রেকর্ড ব্যবহার করেন। তারপর, আপনি সেই ফাংশনটিকে DocumentScreen উইজেটে কল করেন মানগুলি অ্যাক্সেস করতে এবং সেগুলিকে UI-তে প্রতিফলিত করতে।

একটি রেকর্ড তৈরি করুন এবং ফেরত দিন

  • data.dart এ, 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

রেকর্ড ক্ষেত্র অ্যাক্সেস করুন

  1. 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 metadataRecord = document.metadata;              // Add this line.

    return Scaffold(
      appBar: AppBar(
        title: Text(metadataRecord.$1),                    // Modify this line,
      ),
      body: Column(
        children: [
          Center(
            child: Text(
              'Last modified ${metadataRecord.modified}',  // And this one.
            ),
          ),
        ],
      ),
    );
  }
}

metadata গেটার পদ্ধতি একটি রেকর্ড প্রদান করে, যা স্থানীয় পরিবর্তনশীল metadataRecord বরাদ্দ করা হয়। রেকর্ড হল একটি হালকা এবং সহজ উপায় যা একটি একক ফাংশন কল থেকে একাধিক মান ফেরত দেয় এবং একটি ভেরিয়েবলের সাথে বরাদ্দ করে।

সেই রেকর্ডে রচিত পৃথক ক্ষেত্রগুলি অ্যাক্সেস করতে, আপনি রেকর্ডের অন্তর্নির্মিত গেটার সিনট্যাক্স ব্যবহার করতে পারেন।

  • একটি অবস্থানগত ক্ষেত্র পেতে (নাম ছাড়া একটি ক্ষেত্র, যেমন title ), রেকর্ডে গেটার $<num> ব্যবহার করুন। এটি শুধুমাত্র নামহীন ক্ষেত্র ফেরত দেয়।
  • modified এর মত নামযুক্ত ক্ষেত্রগুলির একটি অবস্থানগত গেটার নেই, তাই আপনি সরাসরি এর নাম ব্যবহার করতে পারেন, যেমন metadataRecord.modified

একটি অবস্থানগত ক্ষেত্রের জন্য একজন গেটারের নাম নির্ধারণ করতে, $1 থেকে শুরু করুন এবং নামযুক্ত ক্ষেত্রগুলি এড়িয়ে যান। যেমন:

var record = (named: 'v', 'y', named2: 'x', 'z');
print(record.$1);                               // prints y
print(record.$2);                               // prints z
  1. অ্যাপে প্রদর্শিত JSON মানগুলি দেখতে হট রিলোড করুন। VS কোড ডার্ট প্লাগইন হট-রিলোড হয় যখন আপনি একটি ফাইল সংরক্ষণ করেন।

অ্যাপের একটি স্ক্রিনশট, যা শিরোনাম এবং পরিবর্তিত তারিখ প্রদর্শন করে।

আপনি দেখতে পারেন যে প্রতিটি ক্ষেত্র প্রকৃতপক্ষে তার ধরন বজায় রেখেছে।

  • Text() পদ্ধতিটি একটি স্ট্রিংকে তার প্রথম আর্গুমেন্ট হিসেবে নেয়।
  • modified ক্ষেত্রটি একটি তারিখের সময়, এবং স্ট্রিং ইন্টারপোলেশন ব্যবহার করে একটি String -এ রূপান্তরিত হয়।

বিভিন্ন ধরণের ডেটা ফেরত দেওয়ার অন্য টাইপ-নিরাপদ উপায় হল একটি ক্লাস সংজ্ঞায়িত করা, যা আরও ভার্বস।

6. নিদর্শন সঙ্গে ম্যাচ এবং ধ্বংস

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

একটি প্যাটার্ন এমন একটি কাঠামোকে প্রতিনিধিত্ব করে যা এক বা একাধিক মান নিতে পারে, যেমন একটি ব্লুপ্রিন্ট। নিদর্শনগুলি মিল কিনা তা নির্ধারণ করতে প্রকৃত মানের সাথে তুলনা করে৷

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

স্থানীয় ভেরিয়েবলে একটি রেকর্ড ধ্বংস করুন

  1. metadata কল করার জন্য 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: modified) = document.metadata;   // Modify

    return Scaffold(
      appBar: AppBar(
        title: Text(title),                                  // Modify
      ),
      body: Column(
        children: [
          Center(
            child: Text(
              'Last modified $modified',                     // Modify
            ),
          ),
        ],
      ),
    );
  }
}

রেকর্ড প্যাটার্নে (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 লিখতে পারেন।

  1. আগের ধাপের মতো একই ফলাফল দেখতে হট রিলোড করুন। আচরণ ঠিক একই; আপনি শুধু আপনার কোড আরো সংক্ষিপ্ত করেছেন.

7. ডেটা বের করতে নিদর্শন ব্যবহার করুন

নির্দিষ্ট প্রেক্ষাপটে, প্যাটার্নগুলি কেবল মেলে না এবং ধ্বংস করে না কিন্তু প্যাটার্নটি মেলে কি না তার উপর ভিত্তি করে কোডটি কী করে সে সম্পর্কেও সিদ্ধান্ত নিতে পারে। এগুলোকে বলা হয় খণ্ডনযোগ্য নিদর্শন

আপনি শেষ ধাপে যে পরিবর্তনশীল ঘোষণার প্যাটার্ন ব্যবহার করেছেন তা একটি অকাট্য প্যাটার্ন : মানটি অবশ্যই প্যাটার্নের সাথে মেলে বা এটি একটি ত্রুটি এবং ধ্বংস হবে না। কোনো পরিবর্তনশীল ঘোষণা বা অ্যাসাইনমেন্ট চিন্তা করুন; আপনি একটি ভেরিয়েবলের মান নির্ধারণ করতে পারবেন না যদি তারা একই ধরনের না হয়।

অন্যদিকে, অস্বীকারযোগ্য নিদর্শনগুলি নিয়ন্ত্রণ প্রবাহ প্রসঙ্গে ব্যবহৃত হয়:

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

প্যাটার্ন ছাড়া JSON মান পড়ুন

এই বিভাগে, আপনি প্যাটার্ন ম্যাচিং ছাড়াই ডেটা পড়েন যে প্যাটার্নগুলি আপনাকে JSON ডেটার সাথে কাজ করতে সাহায্য করতে পারে।

  • metadata পূর্ববর্তী সংস্করণটিকে এমন একটি দিয়ে প্রতিস্থাপন করুন যা _json মানচিত্র থেকে মানগুলি পড়ে। Document ক্লাসে metadata এই সংস্করণটি অনুলিপি করুন এবং আটকান:

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                                                // Modify from here...
        case {
          'metadata': {
            'title': String title,
            'modified': String localModified,
          }
        }) {
      return (title, modified: DateTime.parse(localModified));
    } else {
      throw const FormatException('Unexpected JSON');
    }                                                        // to here.
  }
}

এখানে, আপনি একটি নতুন ধরনের if-statement দেখতে পাচ্ছেন (Dart 3-এ প্রবর্তিত), if-case । কেস বডি শুধুমাত্র তখনই চালায় যদি কেস প্যাটার্ন _json এর ডেটার সাথে মেলে। এই ম্যাচটি ইনকামিং JSON যাচাই করার জন্য metadata প্রথম সংস্করণে আপনি যে চেকগুলি লিখেছিলেন তা সম্পন্ন করে৷ এই কোড নিম্নলিখিত যাচাই করে:

  • _json একটি মানচিত্র প্রকার।
  • _json একটি metadata কী রয়েছে।
  • _json শূন্য নয়।
  • _json['metadata'] এছাড়াও একটি মানচিত্র প্রকার।
  • _json['metadata'] কী title এবং modified রয়েছে।
  • title এবং localModified স্ট্রিং এবং শূন্য নয়।

যদি মান মেলে না, প্যাটার্নটি খণ্ডন করে (সম্পাদনা চালিয়ে যেতে অস্বীকার করে) এবং else ধারায় এগিয়ে যায়। ম্যাচটি সফল হলে, প্যাটার্নটি title মানগুলিকে ধ্বংস করে এবং মানচিত্র থেকে modified এবং নতুন স্থানীয় ভেরিয়েবলের সাথে আবদ্ধ করে।

প্যাটার্নগুলির একটি সম্পূর্ণ তালিকার জন্য, বৈশিষ্ট্য স্পেসিফিকেশনের প্যাটার্ন বিভাগে টেবিলটি দেখুন।

8. আরও প্যাটার্নের জন্য অ্যাপটি প্রস্তুত করুন

এখন পর্যন্ত, আপনি 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 তৈরি করতে ব্যবহার করেন। একটি পরিচিত যদি-কেস বিবৃতি বৈধতা সম্পাদন করে এবং blocksJson নামে একটি নতুন List blocks মেটাডেটার মান নিক্ষেপ করে (প্যাটার্ন ছাড়া, কাস্ট করার জন্য আপনার toList() পদ্ধতির প্রয়োজন হবে)।

তালিকা আক্ষরিক Block অবজেক্ট দিয়ে নতুন তালিকা পূরণ করার জন্য একটি সংগ্রহ রয়েছে।

এই বিভাগটি এমন কোনো প্যাটার্ন-সম্পর্কিত বৈশিষ্ট্য উপস্থাপন করে না যা আপনি ইতিমধ্যে এই কোডল্যাবে চেষ্টা করেননি। পরবর্তী ধাপে, আপনি আপনার UI এ তালিকা আইটেম রেন্ডার করার জন্য প্রস্তুত হন।

9. নথি প্রদর্শন করতে নিদর্শন ব্যবহার করুন

আপনি এখন সফলভাবে আপনার JSON ডেটা ধ্বংস এবং পুনর্গঠন, একটি if-case স্টেটমেন্ট এবং খণ্ডনযোগ্য প্যাটার্ন ব্যবহার করে। কিন্তু যদি-কেস প্যাটার্নের সাথে আসা ফ্লো স্ট্রাকচারগুলিকে নিয়ন্ত্রণ করার জন্য শুধুমাত্র একটি উন্নতি। এখন, আপনি বিবৃতি পরিবর্তন করতে খণ্ডনযোগ্য নিদর্শন সম্পর্কে আপনার জ্ঞান প্রয়োগ করুন।

সুইচ স্টেটমেন্ট সহ প্যাটার্ন ব্যবহার করে কি রেন্ডার করা হয়েছে তা নিয়ন্ত্রণ করুন

  • 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 পদ্ধতিতে সুইচ স্টেটমেন্ট block অবজেক্টের type ফিল্ডে সুইচ করে।

  1. প্রথম কেস স্টেটমেন্ট একটি ধ্রুবক স্ট্রিং প্যাটার্ন ব্যবহার করে। block.type ধ্রুবক মান h1 এর সমান হলে প্যাটার্নটি মেলে।
  2. দ্বিতীয় কেস স্টেটমেন্ট তার সাবপ্যাটার্ন হিসাবে দুটি ধ্রুবক স্ট্রিং প্যাটার্ন সহ একটি লজিক্যাল-বা প্যাটার্ন ব্যবহার করে। block.type সাব-প্যাটার্ন p বা checkbox সাথে মিলে গেলে প্যাটার্নটি মেলে।
  1. চূড়ান্ত ক্ষেত্রে একটি ওয়াইল্ডকার্ড প্যাটার্ন , _ . সুইচ ক্ষেত্রে ওয়াইল্ডকার্ডগুলি অন্য সবকিছুর সাথে মেলে। তারা default ধারাগুলির মতোই আচরণ করে, যেগুলি এখনও সুইচ বিবৃতিতে অনুমোদিত (তারা একটু বেশি শব্দযুক্ত)।

যেখানেই প্যাটার্ন অনুমোদিত সেখানে ওয়াইল্ডকার্ড প্যাটার্ন ব্যবহার করা যেতে পারে—উদাহরণস্বরূপ, একটি পরিবর্তনশীল ঘোষণা প্যাটার্নে: var (title, _) = document.metadata;

এই প্রসঙ্গে, ওয়াইল্ডকার্ড কোনো পরিবর্তনশীলকে আবদ্ধ করে না। এটি দ্বিতীয় ক্ষেত্রটি বাতিল করে দেয়।

পরবর্তী বিভাগে, আপনি Block অবজেক্টগুলি প্রদর্শন করার পরে আরও সুইচ বৈশিষ্ট্য সম্পর্কে শিখবেন।

নথির বিষয়বস্তু প্রদর্শন করুন

DocumentScreen উইজেটের build পদ্ধতিতে getBlocks() কল করে Block অবজেক্টের তালিকা ধারণ করে এমন একটি স্থানীয় ভেরিয়েবল তৈরি করুন।

  1. এই সংস্করণের সাথে 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 উইজেট তৈরি করে।

  1. অ্যাপ্লিকেশনটি চালান, এবং তারপরে আপনি স্ক্রিনে উপস্থিত ব্লকগুলি দেখতে পাবেন:

JSON ডেটার 'ব্লক' বিভাগ থেকে সামগ্রী প্রদর্শন করে অ্যাপের স্ক্রিনশট।

10. সুইচ এক্সপ্রেশন ব্যবহার করুন

প্যাটার্নগুলি switch এবং case জন্য প্রচুর ক্ষমতা যুক্ত করে। এগুলিকে আরও জায়গায় ব্যবহারযোগ্য করতে, ডার্টের সুইচ এক্সপ্রেশন রয়েছে৷ মামলার একটি সিরিজ একটি পরিবর্তনশীল অ্যাসাইনমেন্ট বা রিটার্ন স্টেটমেন্টে সরাসরি একটি মান প্রদান করতে পারে।

সুইচ স্টেটমেন্টকে একটি সুইচ এক্সপ্রেশনে রূপান্তর করুন

ডার্ট বিশ্লেষক আপনাকে আপনার কোডে পরিবর্তন করতে সহায়তা করার জন্য সহায়তা প্রদান করে।

  1. আপনার কার্সারকে পূর্ববর্তী বিভাগ থেকে সুইচ স্টেটমেন্টে নিয়ে যান।
  2. উপলব্ধ সহায়তাগুলি দেখতে লাইটবাল্বটিতে ক্লিক করুন৷
  3. অভিব্যক্তি সহায়তা সুইচ করতে রূপান্তর নির্বাচন করুন।

VS কোডে উপলব্ধ 'কনভার্ট টু সুইচ এক্সপ্রেশন' সহায়তার একটি স্ক্রিনশট।

এই কোডের নতুন সংস্করণটি এইরকম দেখাচ্ছে:

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 কীওয়ার্ডটি সরিয়ে দেয় এবং কেস বডি থেকে প্যাটার্নটি আলাদা করতে => ব্যবহার করে। সুইচ স্টেটমেন্টের বিপরীতে, সুইচ এক্সপ্রেশনগুলি একটি মান প্রদান করে এবং যেখানে একটি এক্সপ্রেশন ব্যবহার করা যেতে পারে সেখানে ব্যবহার করা যেতে পারে।

11. অবজেক্ট প্যাটার্ন ব্যবহার করুন

ডার্ট একটি বস্তু-ভিত্তিক ভাষা, তাই নিদর্শনগুলি সমস্ত বস্তুর জন্য প্রযোজ্য। এই ধাপে, আপনি একটি অবজেক্ট প্যাটার্ন চালু করুন এবং আপনার UI এর তারিখ রেন্ডারিং লজিক উন্নত করতে অবজেক্টের বৈশিষ্ট্যগুলিকে ধ্বংস করুন।

বস্তুর নিদর্শন থেকে বৈশিষ্ট্য বের করুন

এই বিভাগে, আপনি প্যাটার্ন ব্যবহার করে শেষ পরিবর্তিত তারিখটি কীভাবে প্রদর্শিত হয় তা উন্নত করেন।

  • main.dartformatDate পদ্ধতি যোগ করুন:

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 । সিনট্যাক্স দেখে মনে হচ্ছে এটি একটি সময়কাল অবজেক্ট তৈরি করছে, তবে এটি আসলে difference অবজেক্টের ক্ষেত্রগুলি অ্যাক্সেস করছে।

প্রথম তিনটি ক্ষেত্রে ধ্রুবক সাবপ্যাটার্ন 0 , 1 , এবং -1 ব্যবহার করে অবজেক্ট প্রপার্টি inDays সাথে মেলে এবং সংশ্লিষ্ট স্ট্রিং ফেরত দেয়।

শেষ দুটি কেস আজ, গতকাল এবং আগামীকালের পরে সময়কাল পরিচালনা করে:

  • যদি isNegative সম্পত্তি বুলিয়ান ধ্রুবক প্যাটার্ন true এর সাথে মেলে, যার অর্থ পরিবর্তনের তারিখ অতীতে ছিল, এটি দিন আগে প্রদর্শন করে।
  • যদি সেই ক্ষেত্রে পার্থক্য ধরা না পড়ে, তাহলে সময়কাল অবশ্যই একটি ধনাত্মক সংখ্যক দিনের হতে হবে ( isNegative: false দিয়ে স্পষ্টভাবে যাচাই করার প্রয়োজন নেই), তাই পরিবর্তনের তারিখটি ভবিষ্যতে এবং এখন থেকে দিনগুলি প্রদর্শন করে৷

সপ্তাহের জন্য বিন্যাস যুক্তি যোগ করুন

  • আপনার ফর্ম্যাটিং ফাংশনে দুটি নতুন কেস যুক্ত করুন যাতে 7 দিনের বেশি সময়কাল শনাক্ত করা যায় যাতে 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 কীওয়ার্ড ব্যবহার করে।
  • এগুলি যদি-কেস, সুইচ স্টেটমেন্ট এবং সুইচ এক্সপ্রেশনে ব্যবহার করা যেতে পারে।
  • একটি প্যাটার্নের সাথে মিলে যাওয়ার পরে তারা শুধুমাত্র একটি শর্ত যোগ করে।
  • যদি গার্ড ক্লজটি মিথ্যা বলে মূল্যায়ন করে, তবে পুরো প্যাটার্নটি খণ্ডন করা হয় এবং মৃত্যুদন্ড পরবর্তী ক্ষেত্রে চলে যায়।

UI-তে নতুন ফর্ম্যাট করা তারিখ যোগ করুন

  1. অবশেষে, 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]);
              },
            ),
          ),
        ],
      ),
    );
  }
}
  1. আপনার অ্যাপে পরিবর্তনগুলি দেখতে হট রিলোড করুন:

অ্যাপের একটি স্ক্রিনশট যা ফর্ম্যাটডেট() ফাংশন ব্যবহার করে 'শেষ পরিবর্তন: 2 সপ্তাহ আগে' একটি স্ট্রিং প্রদর্শন করে।

12. সম্পূর্ণ সুইচিংয়ের জন্য একটি ক্লাস সীলমোহর করুন

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

যখন একটি সুইচের প্রতিটি কেস পরিচালনা করা হয়, তখন এটিকে একটি সম্পূর্ণ সুইচ বলা হয়। উদাহরণস্বরূপ, একটি bool টাইপ চালু করা সম্পূর্ণ হয় যখন এতে true এবং false জন্য কেস থাকে। enum টাইপ চালু করা সম্পূর্ণ হয় যখন enum-এর প্রতিটি মানের ক্ষেত্রেও থাকে, কারণ enums একটি নির্দিষ্ট সংখ্যক ধ্রুবক মানের প্রতিনিধিত্ব করে।

Dart 3 নতুন ক্লাস মডিফায়ার sealed করে অবজেক্ট এবং ক্লাস হায়ারার্কিতে এক্সপেস্টেভনেস চেক করছে । সিল করা সুপারক্লাস হিসাবে আপনার Block ক্লাস রিফ্যাক্টর করুন।

সাবক্লাস তৈরি করুন

  • data.dart এ, তিনটি নতুন ক্লাস তৈরি করুন — HeaderBlock , ParagraphBlock , এবং CheckboxBlock — যা Block প্রসারিত করে:

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 হিসাবে চিহ্নিত করুন। তারপর, যদি-কেসটিকে একটি সুইচ এক্সপ্রেশন হিসাবে রিফ্যাক্টর করুন যা 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 কীওয়ার্ডটি একটি ক্লাস সংশোধক যার মানে আপনি শুধুমাত্র একই লাইব্রেরিতে এই ক্লাসটি প্রসারিত বা প্রয়োগ করতে পারেন। যেহেতু বিশ্লেষক এই শ্রেণীর সাব-টাইপগুলি জানেন, তাই যদি একটি সুইচ তাদের একটিকে কভার করতে ব্যর্থ হয় এবং সম্পূর্ণ না হয় তবে এটি একটি ত্রুটি রিপোর্ট করে।

উইজেট প্রদর্শন করার জন্য একটি সুইচ এক্সপ্রেশন ব্যবহার করুন

  1. প্রতিটি ক্ষেত্রে অবজেক্ট প্যাটার্ন ব্যবহার করে এমন একটি সুইচ এক্সপ্রেশন সহ main.dart এ BlockWidget ক্লাস আপডেট করুন:

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 এলিমেন্টে পাঠাতে পারবেন, যেমন আগে প্রয়োজন আলাদা রিটার্ন স্টেটমেন্টের বিপরীতে।

  1. প্রথমবার রেন্ডার করা চেকবক্স JSON ডেটা দেখতে হট রিলোড করুন:

অ্যাপের একটি স্ক্রিনশট যা 'Learn Dart 3' চেকবক্স প্রদর্শন করে

13. অভিনন্দন

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

বিভিন্ন প্যাটার্নের ধরন, বিভিন্ন প্রেক্ষাপট যেখানে তারা উপস্থিত হতে পারে এবং সাবপ্যাটার্নের সম্ভাব্য নেস্টিং আচরণের সম্ভাবনাকে আপাতদৃষ্টিতে অন্তহীন করে তোলে। কিন্তু তারা দেখতে সহজ.

আপনি প্যাটার্ন ব্যবহার করে Flutter-এ বিষয়বস্তু প্রদর্শনের সব ধরনের উপায় কল্পনা করতে পারেন। প্যাটার্ন ব্যবহার করে, আপনি কোডের কয়েকটি লাইনে আপনার UI তৈরি করতে নিরাপদে ডেটা বের করতে পারেন।

এরপর কি?

  • ডার্ট ডকুমেন্টেশনের ভাষা বিভাগে প্যাটার্ন, রেকর্ড, বর্ধিত সুইচ এবং কেস এবং ক্লাস মডিফায়ারের ডকুমেন্টেশন দেখুন।

রেফারেন্স ডক্স

flutter/codelabs রিপোজিটরিতে ধাপে ধাপে সম্পূর্ণ নমুনা কোড দেখুন।

প্রতিটি নতুন বৈশিষ্ট্যের জন্য গভীরতার স্পেসিফিকেশনের জন্য, মূল ডিজাইন ডক্স দেখুন: