ذمہ داری ڈیزائن پیٹرن کا سلسلہ: ایک وقت میں ایک ہینڈلر میں پیچیدہ کاروباری قواعد کو الگ کریں۔

ہر نظام، کسی نہ کسی وقت، ان خصوصیات کے ساتھ ختم ہوتا ہے جنہیں کوئی چھونا نہیں چاہتا۔

یہ چھوٹا شروع ہوتا ہے۔ سادہ توثیق، ایک اگر بیان یہاں، ایک اور بیان۔ پھر ضروریات بڑھتی ہیں اور مزید شرائط شامل کی جاتی ہیں۔ خصوصیات لمبی ہو جاتی ہیں۔ کسی نے ایک تبصرہ شامل کیا: "پہلے پوری چیز کو پڑھے بغیر ترمیم نہ کریں۔” فنکشن گزرنے کی رسم بن جاتا ہے۔ آن بورڈنگ کے دوران نئے ڈویلپرز کو اس بارے میں خبردار کیا جاتا ہے۔

ایسا اس وقت ہوتا ہے جب پیچیدہ کاروباری قواعد کو ایک جگہ پر بغیر کسی جان بوجھ کر ان پر مشتمل ڈھانچے کے ڈھیر لگا دیا جاتا ہے۔

اس کو روکنے کے لیے ذمہ داری کا ایک سلسلہ موجود ہے۔ ایک ایسے طریقہ کے بجائے ہینڈلرز کی ایک مرکوز سلسلہ بنائیں جو سب کچھ جانتا ہے اور سب کچھ کرتا ہے۔ ہر ہینڈلر ایک اصول جانتا ہے اور جانچتا ہے کہ آیا درخواست اس اصول کو پاس کرتی ہے۔ اگر ایسا ہے تو، درخواست اگلے ہینڈلر کے پاس جاتی ہے۔ ورنہ سلسلہ وہیں رک جاتا ہے۔

کوئی ہینڈلر زنجیر کی لمبائی نہیں جانتا۔ کوئی ہینڈلر نہیں جانتا کہ اس سے پہلے یا بعد میں کیا آتا ہے۔ ہر شخص اپنا کام خود کرتا ہے اور یہاں رکنے یا آگے جانے کا فیصلہ کرتا ہے۔

انڈیکس

ذمہ داری پیٹرن کا سلسلہ کیا ہے؟

ذمہ داری کا سلسلہ ایک طرز عمل ڈیزائن پیٹرن ہے جو درخواستوں کو ہینڈلرز کی زنجیر کے ساتھ منتقل کرنے کی اجازت دیتا ہے۔ سلسلہ میں موجود ہر ہینڈلر درخواست پر کارروائی کرتا ہے اور فیصلہ کرتا ہے کہ آیا سلسلہ کو روکنا ہے یا درخواست کو اگلے ہینڈلر کو بھیجنا ہے۔

پیٹرن پیداوار کے نظام میں تین اہم چیزیں پیش کرتے ہیں:

سب سے پہلے، یہ درخواست بھیجنے والے اور وصول کنندہ کو الگ کرتا ہے۔ کوڈ جو لین دین کی توثیق کا آغاز کرتا ہے وہ نہیں جان سکتا کہ کون سا ہینڈلر بالآخر اس پر کارروائی کرے گا یا اسے روکے گا۔ سلسلہ شروع ہوتا ہے۔

دوسرا، یہ فی ہینڈلر ایک ہی ذمہ داری دیتا ہے۔ ہر ہینڈلر بالکل ایک کاروباری اصول کا مالک ہے۔ ایک طبقے کے قوانین تبدیل ہونے پر اس میں ترمیم کریں۔ اور کچھ نہیں بدلتا۔

تیسرا، یہ سلسلہ کو کمپوز ایبل بناتا ہے۔ آپ موجودہ ہینڈلر کوڈ کو چھوئے بغیر ہینڈلرز کو شامل، ہٹا سکتے یا دوبارہ ترتیب دے سکتے ہیں۔ نئی تعمیل کی ضرورت موجودہ طریقہ کار کے اندر ایک نئی شاخ کے بجائے سلسلہ سے منسلک ایک نیا ہینڈلر ہوگا۔

مسئلہ یہ حل کرتا ہے

پیٹرن کے بغیر لین دین کی توثیق درج ذیل ہے:

void handleTransaction(Transaction transaction) {
  if (transaction.isFraud) {
    // block transaction
    return;
  }

  if (!transaction.isKycVerified) {
    // reject transaction
    return;
  }

  if (!transaction.isAccountActive) {
    // reject transaction
    return;
  }

  if (transaction.amount < 50000) {
    // junior officer approval
    return;
  }

  if (transaction.amount <= 200000) {
    // mid level approval
    return;
  }

  if (transaction.amount <= 1000000) {
    // manager approval
    return;
  }

  // executive approval
}

یہ آج کام کرتا ہے۔ کل ہماری کمپلائنس ٹیم کریڈٹ سکور چیک شامل کرے گی۔ فراڈ ٹیم نے اسپیڈ چیک کا اضافہ کیا۔ قانونی ٹیم پابندیوں کا جائزہ لینے کا مرحلہ شامل کرتی ہے۔ پروڈکٹ مینیجر روزانہ کی حد کی جانچ شامل کرتا ہے۔

تمام نئے قوانین اسی طرح کام کرتے ہیں۔ اس طریقہ کار میں 50 لائنیں لگتی ہیں۔ پھر ایک سو۔ حالات ان طریقوں سے تعامل کرتے ہیں جن کے بارے میں سوچنا مشکل ہوتا ہے۔ اس کی جانچ کرنے کے لیے، آپ کو تمام ممکنہ جھنڈے کے مجموعے ترتیب دینے کی ضرورت ہے۔ ایک حالت میں ایک بگ اس کے نیچے دیگر تمام حالات کو متاثر کر سکتا ہے۔

ذمہ داری کا سلسلہ یہ بتاتا ہے: ہر اصول کا اپنا ہینڈلر ہوتا ہے۔ ہینڈلرز کو ایک ساتھ جوڑیں۔ سلسلہ شروع کرنے والے طریقہ کو قواعد جاننے کی ضرورت نہیں ہے۔ یہ صرف سلسلہ شروع کرتا ہے اور راستے میں نہیں آتا ہے۔

بنیادی اجزاء

پیٹرن کے تین اجزاء ہیں:

1. ہینڈلر انٹرفیس

یہ ایک معاہدہ ہے جسے سلسلہ میں موجود تمام ہینڈلرز کو لاگو کرنا چاہیے۔ یہ اعلان کرتا ہے کہ درخواستوں کو کیسے ہینڈل کیا جائے گا اور چین ہینڈلرز کو ایک ساتھ ایک طریقہ کار فراہم کرتا ہے۔ تمام کنکریٹ ہینڈلرز اس کو بڑھاتے یا نافذ کرتے ہیں۔

2. کنکریٹ ہینڈلر

یہ ہے اصل نفاذ۔ ہر ایک بالکل ایک کاروباری اصول کا مالک ہے۔ چیک کریں کہ آیا درخواست قواعد پر پورا اترتی ہے۔ اگر کوئی قاعدہ ناکام ہوجاتا ہے تو، سلسلہ بند کریں اور ناکامی کو ہینڈل کریں۔ اگر اصول گزر جاتا ہے، تو یہ اگلے ہینڈلر کو کال کرتا ہے اور درخواست کو آگے بھیج دیتا ہے۔

3. سلسلہ

یہ کلاس نہیں ہے۔ ہینڈلرز کو ایک ساتھ باندھنے کا عمل۔ setNext طریقہ اپنی ساخت کی جڑ یا انحصار انجیکشن سیٹ اپ سے سلسلہ بنائیں۔ کنکشن کا حکم پھانسی کا حکم ہے.

حقیقی زندگی کی مثال 1: لین دین کی منظوری کا بہاؤ

Fintech پلیٹ فارمز ہر روز ہزاروں لین دین پر کارروائی کرتے ہیں۔ ہر لین دین کو منظور ہونے سے پہلے کئی تصدیقی اور منظوری کے دروازوں سے گزرنا چاہیے۔ ہر دروازہ خود مختار ہے۔ ہر شخص کی ایک ذمہ داری ہے۔

گیٹ آرڈر میں:

  1. فراڈ چیک: کیا اس لین دین کو دھوکہ دہی کے طور پر نشان زد کیا گیا ہے؟

  2. KYC کی توثیق: کیا صارف نے شناخت کی تصدیق مکمل کر لی ہے؟

  3. اکاؤنٹ کی حیثیت: کیا آپ کا اکاؤنٹ فعال اور اچھی حالت میں ہے؟

  4. منظوری کی سطح: کس سطح کے ایگزیکٹوز کو اس رقم کو منظور کرنے کا اختیار ہے؟

تجارتی ماڈل

class Transaction {
  final num amount;
  final bool isFraud;
  final bool isKycVerified;
  final bool isAccountActive;

  const Transaction({
    required this.amount,
    required this.isFraud,
    required this.isKycVerified,
    required this.isAccountActive,
  });
}

ٹرانزیکشن ماڈل وہ تمام ڈیٹا پاس کرتا ہے جو ہر ہینڈلر کو فیصلے کرنے کے لیے درکار ہوتا ہے۔ آپ صرف اپنے ڈیٹا کے مالک ہیں اور کچھ نہیں۔ یہاں توثیق کی کوئی منطق نہیں ہے۔

ہینڈلر انٹرفیس

abstract class TransactionHandler {
  TransactionHandler? _next;

  void setNext(TransactionHandler handler) {
    _next = handler;
  }

  void handle(Transaction transaction);

  void passToNext(Transaction transaction) {
    if (_next != null) {
      _next!.handle(transaction);
    } else {
      print('End of chain reached with no handler stopping the transaction');
    }
  }
}

TransactionHandler یہ وہ معاہدہ ہے جسے تمام ہینڈلرز لاگو کرتے ہیں۔

_next null ممکن ہے کیونکہ سلسلہ میں آخری ہینڈلر کا کوئی اگلا ہینڈلر نہیں ہے۔ اسے کالعدم قرار دینا اور کال کرنے سے پہلے اسے چیک کرنا سلسلہ کے آخر میں صفر پوائنٹر کے تصادم کو روک دے گا۔

setNext ایک ہینڈلر کو اگلے ہینڈلر سے جوڑیں۔ جب ہم سلسلہ بناتے ہیں تو ہم اسے کہتے ہیں۔

passToNext یہ ایک مددگار طریقہ ہے جسے تمام کنکریٹ ہینڈلرز کال کرتے ہیں جب کوئی اصول گزر جاتا ہے۔ چیک کریں کہ آیا مندرجہ ذیل ہینڈلر اسے کال کرنے سے پہلے موجود ہے: یہ اس وقت لاگ ان ہوتا ہے جب سلسلہ کے اختتام تک پہنچ جاتا ہے بغیر کسی ہینڈلر کے لین دین کو روکے۔ ایک حقیقی نظام میں، یہ ایک انتباہ کا سبب بنے گا کیونکہ اس کا مطلب ہے کہ سلسلہ صحیح طریقے سے ترتیب نہیں دیا گیا ہے۔

کنکریٹ ہینڈلر

class FraudHandler extends TransactionHandler {
  @override
  void handle(Transaction transaction) {
    if (transaction.isFraud) {
      print('Transaction blocked: fraud detected');
      return;
    }
    print('Fraud check passed');
    passToNext(transaction);
  }
}

FraudHandler یہ پہلا دروازہ ہے۔ اگر ٹرانزیکشن کو دھوکہ دہی کے طور پر نشان زد کیا گیا ہے، تو یہ ایک مسترد پیغام پرنٹ کرتا ہے اور اسے واپس کرتا ہے۔ سلسلہ یہیں رک جاتا ہے۔ دوسرے ہینڈلرز اس لین دین کو نہیں دیکھ سکتے ہیں۔ اگر فراڈ چیک پاس ہو جاتا ہے تو وہ آپ کو کال کریں گے۔ passToNext لین دین اگلے ہینڈلر کی طرف جاتا ہے۔

class KycHandler extends TransactionHandler {
  @override
  void handle(Transaction transaction) {
    if (!transaction.isKycVerified) {
      print('Transaction blocked: KYC verification incomplete');
      return;
    }
    print('KYC check passed');
    passToNext(transaction);
  }
}

KycHandler تصدیق کریں کہ صارف نے شناخت کی تصدیق مکمل کر لی ہے۔ نہیں تو سلسلہ رک جائے گا۔ اگر ایسا ہے تو، لین دین آگے بڑھے گا۔ یہ ہینڈلر فراڈ کی تصدیق کے بارے میں کچھ نہیں جانتا ہے۔ ہم آپ کے اکاؤنٹ کی حیثیت کے بارے میں کچھ نہیں جانتے ہیں۔ ایک اصول کا مالک۔

class AccountHandler extends TransactionHandler {
  @override
  void handle(Transaction transaction) {
    if (!transaction.isAccountActive) {
      print('Transaction blocked: account is not active');
      return;
    }
    print('Account status check passed');
    passToNext(transaction);
  }
}

AccountHandler اپنے اکاؤنٹ کی حیثیت چیک کریں۔ ایک ہی پیٹرن، ایک اصول: روکیں یا گزریں۔

class ApprovalHandler extends TransactionHandler {
  @override
  void handle(Transaction transaction) {
    if (transaction.amount < 50000) {
      print('Approved by Junior Officer — amount: ${transaction.amount}');
      return;
    }

    if (transaction.amount <= 200000) {
      print('Approved by Mid-Level Officer — amount: ${transaction.amount}');
      return;
    }

    if (transaction.amount <= 1000000) {
      print('Approved by Manager — amount: ${transaction.amount}');
      return;
    }

    print('Escalated to Executive Approval — amount: ${transaction.amount}');
    passToNext(transaction);
  }
}

ApprovalHandler یہ آخری دروازہ ہے۔ رقم کی بنیاد پر لین دین کو منظوری کے مناسب درجے تک لے جائیں۔ 50,000 سے کم لین دین کی منظوری جونیئر افسران کے ذریعے دی جاتی ہے۔ درمیانی درجے کے افسران کو 200,000 تک تنخواہ دی جاتی ہے۔ 1,000,000 تک ایڈمنسٹریٹر کے پاس جائیں گے۔ اس سے آگے، ڈیل مزید پھیلتی ہے۔

اس ہینڈلر کو اب بھی بلایا جا سکتا ہے۔ passToNext اگر رقم ایڈمن کی حد سے تجاوز کر جاتی ہے، تو آپ بعد میں اسے چھوئے بغیر سلسلہ میں ایک ایگزیکیوشن ہینڈلر شامل کر سکتے ہیں۔ ApprovalHandler.

چین بنائیں اور چلائیں۔

void main() {
  // create the handlers
  final fraud = FraudHandler();
  final kyc = KycHandler();
  final account = AccountHandler();
  final approval = ApprovalHandler();

  // build the chain
  fraud.setNext(kyc);
  kyc.setNext(account);
  account.setNext(approval);

  // test with a fraudulent transaction
  print('Test 1: Fraudulent Transaction');
  final fraudulentTransaction = Transaction(
    amount: 100000,
    isFraud: true,
    isKycVerified: true,
    isAccountActive: true,
  );
  fraud.handle(fraudulentTransaction);

  // test with unverified KYC
  print('Test 2: KYC Not Verified');
  final unverifiedTransaction = Transaction(
    amount: 50000,
    isFraud: false,
    isKycVerified: false,
    isAccountActive: true,
  );
  fraud.handle(unverifiedTransaction);

  // test with a valid transaction
  print('Test 3: Valid Transaction');
  final validTransaction = Transaction(
    amount: 150000,
    isFraud: false,
    isKycVerified: true,
    isAccountActive: true,
  );
  fraud.handle(validTransaction);

  // test with a high value transaction
  print('Test 4: Executive Level Transaction');
  final executiveTransaction = Transaction(
    amount: 2000000,
    isFraud: false,
    isKycVerified: true,
    isAccountActive: true,
  );
  fraud.handle(executiveTransaction);
}

حساب کتاب:

Test 1: Fraudulent Transaction
Transaction blocked: fraud detected

Test 2: KYC Not Verified
Fraud check passed
Transaction blocked: KYC verification incomplete

Test 3: Valid Transaction
Fraud check passed
KYC check passed
Account status check passed
Approved by Mid-Level Officer — amount: 150000

Test 4: Executive Level Transaction
Fraud check passed
KYC check passed
Account status check passed
Escalated to Executive Approval — amount: 2000000
End of chain reached with no handler stopping the transaction

ٹیسٹ 1 پہلے ہینڈلر پر رک جاتا ہے۔ دھوکہ دہی کے لیے ٹیسٹ 2 پاس ہوا لیکن KYC پر روک دیا گیا۔ ٹیسٹ 3 تمام توثیق کرنے والے ہینڈلرز کو پاس کرتا ہے اور اسے درست منظوری کی پرت کی طرف روانہ کیا جاتا ہے۔ ایڈمن کی حد سے تجاوز کر کے ٹیسٹ 4 کو بڑھایا جاتا ہے۔

کالنگ کوڈ ہمیشہ سے شروع ہوتا ہے: fraud.handle(transaction). مجھے نہیں معلوم کہ کتنے ہینڈلر موجود ہیں۔ آپ نہیں جانتے کہ کون سا ہینڈلر سلسلہ روک دے گا۔ اور میں نہیں جانتا کہ منظوری کا درجہ بندی کیا ہے۔ ٹرانزیکشن کو پہلے ہینڈلر کو منتقل کریں اور سلسلہ سنبھال لے۔

اگلے مہینے، جب ہماری کمپلائنس ٹیم صارف کے استثنیٰ کی جانچ کو شامل کرے گی، ہم صرف ایک UserIdemnityCheck بنائیں گے اور اسے سلسلہ میں شامل کریں گے، اور اس میں کوئی دوسری تبدیلیاں نہیں ہوں گی۔

final indemnity = UserIndemnityStatus();

fraud.setNext(indemnity);
indemnity.setNext(kyc);
kyc.setNext(account);
account.setNext(approval);

ایک نئی کلاس اور ایک اپ ڈیٹ شدہ چین سیٹ اپ۔ تمام موجودہ ہینڈلرز برقرار ہیں۔

حقیقی زندگی کی مثال 2: صارف کی آن بورڈنگ کی تصدیق

صارفین رجسٹریشن فارم کو مکمل اور جمع کراتے ہیں۔ اکاؤنٹ بنانے سے پہلے، آپ کی درخواست کو تصدیق کے کئی مراحل سے گزرنا چاہیے۔ اگر کوئی بھی مرحلہ ناکام ہو جاتا ہے، تو صارف کو ایک مخصوص غلطی موصول ہو گی جس میں یہ واضح ہو جائے گا کہ کیا غلط ہوا ہے۔

یہاں ترتیب میں اقدامات ہیں:

  1. اپنا ای میل چیک کریں: کیا آپ کا ای میل فارمیٹ درست ہے؟

  2. پاس ورڈ کی طاقت: کیا آپ کا پاس ورڈ آپ کی حفاظتی ضروریات کو پورا کرتا ہے؟

  3. عمر کی تصدیق: کیا صارف رجسٹر کرنے کے لیے کافی پرانا ہے؟

  4. ڈپلیکیٹ اکاؤنٹس کی جانچ کریں: کیا یہ ای میل استعمال کرنے والا اکاؤنٹ پہلے سے موجود ہے؟

  5. اکاؤنٹ بنائیں: تمام تصدیقات پاس کریں اور ایک اکاؤنٹ بنائیں۔

رجسٹریشن کی درخواست کا ماڈل

class RegistrationRequest {
  final String email;
  final String password;
  final int age;

  const RegistrationRequest({
    required this.email,
    required this.password,
    required this.age,
  });
}

ہینڈلر انٹرفیس

abstract class RegistrationHandler {
  RegistrationHandler? _next;

  void setNext(RegistrationHandler handler) {
    _next = handler;
  }

  void handle(RegistrationRequest request);

  void passToNext(RegistrationRequest request) {
    if (_next != null) {
      _next!.handle(request);
    }
  }
}

یہ وہی ڈھانچہ ہے جو پہلے تھا۔ کالعدم اگلا، SetNext سلسلہ بناتا ہے اور PassToNext درخواست کو آگے بڑھاتا ہے۔

کنکریٹ ہینڈلر

class EmailValidationHandler extends RegistrationHandler {
  @override
  void handle(RegistrationRequest request) {
    final emailRegex = RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$');

    if (!emailRegex.hasMatch(request.email)) {
      print('Registration failed: invalid email format — ${request.email}');
      return;
    }

    print('Email validation passed');
    passToNext(request);
  }
}

EmailValidationHandler ای میل فارمیٹ چیک کرنے کے لیے ریگولر ایکسپریشنز کا استعمال کریں۔ اگر فارمیٹ غلط ہے، تو یہ ایک مخصوص پیغام کے ساتھ سلسلہ کو فوراً روک دیتا ہے۔ اگر درست ہے تو درخواست آگے بڑھ جاتی ہے۔

class PasswordStrengthHandler extends RegistrationHandler {
  @override
  void handle(RegistrationRequest request) {
    final password = request.password;
    final hasMinLength = password.length >= 8;
    final hasUppercase = password.contains(RegExp(r'[A-Z]'));
    final hasNumber = password.contains(RegExp(r'[0-9]'));
    final hasSpecialChar = password.contains(RegExp(r'[!@#\$%^&*]'));

    if (!hasMinLength || !hasUppercase || !hasNumber || !hasSpecialChar) {
      print('Registration failed: password does not meet security requirements');
      print('Requirements: 8+ characters, uppercase, number, special character');
      return;
    }

    print('Password strength check passed');
    passToNext(request);
  }
}

PasswordStrengthHandler ایک جگہ پر پاس ورڈ کے چار اصول نافذ کریں۔ کم از کم لمبائی، کم از کم ایک بڑے حروف، کم از کم ایک عدد، اور کم از کم ایک خاص حرف۔ اگر ان میں سے کوئی بھی ناکام ہوجاتا ہے، تو صارف کو تمام ضروریات کی وضاحت کرنے والا ایک واضح پیغام موصول ہوگا۔ اگر سب گزر جاتا ہے تو درخواست آگے بڑھ جاتی ہے۔

class AgeVerificationHandler extends RegistrationHandler {
  final int minimumAge;

  AgeVerificationHandler({this.minimumAge = 18});

  @override
  void handle(RegistrationRequest request) {
    if (request.age < minimumAge) {
      print('Registration failed: user must be at least $minimumAge years old');
      return;
    }

    print('Age verification passed');
    passToNext(request);
  }
}

AgeVerificationHandler کم از کم حد کے خلاف صارف کی عمر کی جانچ کریں۔ یہ ہینڈلر کم از کم عمر کو کنسٹرکٹر پیرامیٹر کے طور پر قبول کرتا ہے۔ یہ آپ کو اس میں ترمیم کیے بغیر کلاس کو ترتیب دینے کی اجازت دیتا ہے۔ اگر کسی خاص پروڈکٹ کے لیے کم از کم عمر کی شرط 18 سے 16 تک بدل جاتی ہے، تو آپ زنجیر بناتے وقت صرف ایک مختلف قدر پاس کر سکتے ہیں۔

class DuplicateAccountHandler extends RegistrationHandler {
  final Set existingEmails;

  DuplicateAccountHandler({required this.existingEmails});

  @override
  void handle(RegistrationRequest request) {
    if (existingEmails.contains(request.email)) {
      print('Registration failed: an account already exists with ${request.email}');
      return;
    }

    print('Duplicate account check passed');
    passToNext(request);
  }
}

DuplicateAccountHandler یہ دیکھنے کے لیے چیک کریں کہ آیا فراہم کردہ ای میل استعمال کرنے والا اکاؤنٹ پہلے سے موجود ہے۔ ایک حقیقی نظام میں ہم اسے ذخیرہ یا ڈیٹا بیس کہتے ہیں۔ یہاں ہم نمونوں پر مثال کو مرکوز رکھنے کے لیے ای میلز کا ایک موجودہ سیٹ استعمال کرتے ہیں۔

class AccountCreationHandler extends RegistrationHandler {
  @override
  void handle(RegistrationRequest request) {
    print('All validation passed');
    print('Creating account for: ${request.email}');
    // call account creation service
    print('Account created successfully');
  }
}

AccountCreationHandler یہ آخری ہینڈلر ہے۔ یہ تبھی چلے گا جب تمام سابقہ ​​ہینڈلرز درخواست کو پاس کر چکے ہوں۔ عمل درآمد کے اس مقام تک پہنچنے تک، درخواست کی ہر سطح پر توثیق ہو چکی ہے۔ یہ ہینڈلر صرف ایک اکاؤنٹ بناتا ہے۔

چین بنائیں اور چلائیں۔

void main() {
  final existingEmails = {'existing@seyi.com', 'taken@seyi.com'};

  // create the handlers
  final emailValidation = EmailValidationHandler();
  final passwordStrength = PasswordStrengthHandler();
  final ageVerification = AgeVerificationHandler(minimumAge: 18);
  final duplicateCheck = DuplicateAccountHandler(existingEmails: existingEmails);
  final accountCreation = AccountCreationHandler();

  // build the chain
  emailValidation.setNext(passwordStrength);
  passwordStrength.setNext(ageVerification);
  ageVerification.setNext(duplicateCheck);
  duplicateCheck.setNext(accountCreation);

  // test with invalid email
  print('Test 1: Invalid Email');
  emailValidation.handle(RegistrationRequest(
    email: 'notanemail',
    password: 'SecureP@ss1',
    age: 25,
  ));

  // test with weak password
  print('Test 2: Weak Password');
  emailValidation.handle(RegistrationRequest(
    email: 'user@example.com',
    password: 'weak',
    age: 25,
  ));

  // test with underage user
  print('Test 3: Underage User');
  emailValidation.handle(RegistrationRequest(
    email: 'young@example.com',
    password: 'SecureP@ss1',
    age: 16,
  ));

  // test with duplicate account
  print('Test 4: Duplicate Account');
  emailValidation.handle(RegistrationRequest(
    email: 'existing@example.com',
    password: 'SecureP@ss1',
    age: 25,
  ));

  // test with valid registration
  print('Test 5: Valid Registration');
  emailValidation.handle(RegistrationRequest(
    email: 'newuser@example.com',
    password: 'SecureP@ss1',
    age: 25,
  ));
}

حساب کتاب:

Test 1: Invalid Email
Registration failed: invalid email format — notanemail

Test 2: Weak Password
Email validation passed
Registration failed: password does not meet security requirements
Requirements: 8+ characters, uppercase, number, special character

Test 3: Underage User
Email validation passed
Password strength check passed
Age verification passed
Registration failed: user must be at least 18 years old

Test 4: Duplicate Account
Email validation passed
Password strength check passed
Age verification passed
Duplicate account check passed
Registration failed: an account already exists with existing@example.com

Test 5: Valid Registration
Email validation passed
Password strength check passed
Age verification passed
Duplicate account check passed
All validation passed
Creating account for: newuser@example.com
Account created successfully

ہر ٹیسٹ بالکل صحیح ہینڈلر پر رک جاتا ہے۔ ہر ناکامی کا پیغام مخصوص ہے۔ ایک درست رجسٹریشن ایک اکاؤنٹ بنانے کے لیے پانچوں ہینڈلرز سے گزرے گی۔

نئے تقاضے آنے پر، ہم اکاؤنٹ بنانے سے پہلے فون نمبر کی توثیق کے مرحلے سے گزریں گے: PhoneVerificationHandler اسے ڈپلیکیٹ چیک اور اکاؤنٹ بنانے کے درمیان سلسلہ سے جوڑیں۔ پانچ موجودہ ہینڈلرز مکمل طور پر برقرار رہیں گے۔

کیا چیز ان دو مثالوں کو ایک ساتھ دلچسپ بناتی ہے؟

لین دین کا بہاؤ اور آن بورڈنگ بہاؤ سطح پر ایک جیسے لگ سکتے ہیں، لیکن وہ دو مختلف طریقوں کی نمائندگی کرتے ہیں جن میں پیٹرن کو پیداوار میں استعمال کیا جاتا ہے۔

لین دین کا بہاؤ توثیق ہینڈلرز اور روٹنگ ہینڈلرز کو ایک سلسلہ میں جوڑتا ہے۔ فراڈ، KYC اور اکاؤنٹ پروسیسر آپ کے دروازے پر ہیں۔ اجازت دینے والا ہینڈلر روٹر ہے۔ زنجیر کی پہلے تصدیق کی جاتی ہے اور پھر روٹ کی جاتی ہے۔ یہ ادائیگیوں اور تعمیل کے نظاموں میں عام ہے جہاں مناسب حکام کو بھیجے جانے سے پہلے ہر لین دین کو متعدد آزاد چیک پاس کرنا ضروری ہے۔

آن بورڈنگ فلو ایک خالص تصدیقی سلسلہ ہے۔ ہر ہینڈلر ایک گیٹ ہے۔ حتمی ہینڈلر ایک ایسا کام ہے جو صرف اس صورت میں انجام پاتا ہے جب تمام دروازے گزر جائیں۔ یہ فارم پروسیسنگ، API کی درخواست کی توثیق، اور کثیر مرحلہ تصدیقی بہاؤ میں عام ہے۔

دونوں ایک ہی پیٹرن کا استعمال کرتے ہیں اور اسی طرح سے بنائے گئے ہیں۔ فرق اس بات میں ہے کہ ہینڈلر درخواست کو پاس کرتے وقت کیا کرتا ہے۔

زنجیر کی ذمہ داری کے پیٹرن کو کب استعمال کریں۔

جب آپ کی درخواست کو متعدد آزاد تصدیق یا کارروائی کے مراحل کی ضرورت ہو تو اسے استعمال کریں۔

یہ بھی موزوں ہے اگر وقت کے ساتھ ساتھ چیک کی تعداد یا ترتیب تبدیل ہو جائے۔ نئے اقدامات شامل کرتے وقت یا موجودہ اقدامات کو دوبارہ ترتیب دیتے وقت موجودہ ہینڈلر کوڈ میں ترمیم کرنے کی ضرورت نہیں ہے۔

یہ اچھی طرح سے کام کرتا ہے جب ہر توثیق یا پروسیسنگ مرحلے میں مکمل طور پر آزاد منطق ہو۔ اگر اقدامات ایک دوسرے پر گہرا انحصار کرتے ہیں اور بہت ساری ریاستوں کو بانٹنے کی ضرورت ہے، تو ایک ہی طبقہ صاف ستھرا ہوسکتا ہے۔

جب آپ ہر قدم کو آزادانہ طور پر جانچنے کے قابل ہونا چاہتے ہیں تو یہ مفید ہے۔ چین پیٹرن کے ساتھ ٹیسٹ کریں FraudHandler اس کا مطلب ہے ایک ہینڈلر بنانا، ہینڈل کو لین دین کے ساتھ کال کرنا، اور آؤٹ پٹ چیک کرنا۔ کوئی اور ہینڈلرز شامل نہیں ہیں۔

اور یہ مفید ہے جب آپ کو مختلف حالات میں سلسلہ کی مختلف کنفیگریشنز کی ضرورت ہو۔ ایک جونیئر آفیسر سسٹم میں آفیسر سسٹم کے مقابلے میں ایک چھوٹا سلسلہ ہوسکتا ہے۔ ایک ہی ہینڈلر کو مختلف طریقے سے ترتیب دیا گیا ہے۔

کب استعمال نہ کریں۔

نمونوں سے بچیں اگر صرف ایک یا دو چیک ہوں۔ ایک تجریدی کلاس اور متعدد کنکریٹ کلاسز کی وضاحت کرنے کا اوور ہیڈ سادہ توثیق کے لیے اس کے قابل نہیں ہے۔

یہ بھی بہترین نہیں ہے اگر پروسیسنگ کے مراحل کی ترتیب طے ہو اور کبھی تبدیل نہ ہو۔ اگر سلسلہ ہمیشہ ایک جیسا رہتا ہے تو سادہ سیکوینشنل فنکشن کالز واضح ہو سکتی ہیں۔

اگر آپ کے ہینڈلرز کو ایک دوسرے کو نتائج واپس بھیجنے کی ضرورت ہو تو اسے استعمال نہ کریں۔ پیٹرن بہترین کام کرتا ہے جب ہر ہینڈلر آزادانہ فیصلے کرتا ہے۔ اگر ہینڈلر B کو یہ جاننے کی ضرورت ہے کہ ہینڈلر A نے کیا دریافت کیا، تو ایک مختلف طریقہ پر غور کریں۔

اور اگر آپ کو پچھلے نتائج سے قطع نظر تمام ہینڈلرز کے عمل درآمد کی ضمانت دینے کی ضرورت ہو تو یہ اچھا انتخاب نہیں ہے۔ جب ہینڈلر درخواست پر کارروائی کرتا ہے تو ذمہ داری کا سلسلہ رک جاتا ہے۔ اگر تمام اقدامات کو ہر وقت انجام دینے کی ضرورت ہے تو، ایک مڈل ویئر پائپ لائن یا ڈیکوریٹر پیٹرن زیادہ مناسب ہوسکتا ہے۔

نتیجہ

ذمہ داری کا سلسلہ اس مسئلے کو حل کرتا ہے جس کا کسی بھی بڑھتے ہوئے نظام کو بالآخر سامنا کرنا پڑتا ہے۔ کاروباری قواعد جمع ہوتے ہیں اور توثیق کی منطق پھیل جاتی ہے۔ جو دس لائنوں سے شروع ہوتا ہے وہ سو لائنیں بن جاتا ہے۔ حالات ان طریقوں سے تعامل کرتے ہیں جسے اب کوئی بھی پوری طرح سے نہیں سمجھتا ہے۔ کوئی اسے چھونا نہیں چاہتا۔

پیٹرن ایک راستہ فراہم کرتے ہیں. ہر کاروباری اصول کا اپنا ہینڈلر ہوتا ہے۔ ہر ہینڈلر کی ایک ذمہ داری ہے اور وہ ایک فیصلہ کرتا ہے۔ یہیں رکیں یا آگے۔ زنجیر کنفیگریشن پرت پر ایک بار بنتی ہے۔ ہینڈلرز کو ایک دوسرے کے بارے میں کچھ جاننے کی ضرورت نہیں ہے۔

لین دین کی منظوری کے بہاؤ میں ایک نیا تعمیل اصول شامل کرنے کا مطلب ہے ایک نئی ہینڈلر کلاس۔ آن بورڈنگ فلو میں ایک نیا تصدیقی مرحلہ شامل کرنے کا مطلب ہے ایک نئی ہینڈلر کلاس۔ دونوں صورتوں میں، کوئی اور چیز نہیں بدلتی۔

یہ نمونہ کا وعدہ ہے۔ ترمیم کے بجائے اضافے پیچیدگی میں اضافہ کرتے ہیں۔ الگ تھلگ، جانچنے کے قابل، اور بدلنے کے قابل کاروباری اصول۔ ایک ایسا نظام جو آپ کو ہر بار زیادہ قرض جمع کیے بغیر نئی ضروریات کو جذب کرنے کی اجازت دیتا ہے۔

اس طرز عمل کو لاگو کرنے سے آپ کے کوڈ میں تنظیم اور توسیع پذیری کی سطح لانے میں مدد ملتی ہے اور مستقبل قریب میں شامل کیے جانے والے اضافی کاروباری قواعد کی بنیاد پر انتظام کرنا آسان بناتا ہے۔

کوڈنگ کا مزہ لیں !!

Scroll to Top