উপসংহার

Knowing When Not To

"Now go write the code your future self will thank you for."

প্যাটার্ন চেনা এক দক্ষতা; কখন প্যাটার্ন লাগবে না তা বোঝা আরও বড় দক্ষতা।

~৮ মিনিট৮টি স্লাইড

প্যাটার্ন হলো লেন্স

নয়টি অধ্যায় জুড়ে আমরা দেখেছি লারাভেল কোন আইডিয়াগুলো সবখানে পুনঃব্যবহার করে। এখন হয়তো এমন জায়গাতেও সেগুলো দেখছেন, যা আমরা উল্লেখই করিনি।

এটাই উদ্দেশ্য। Pattern recognition চক্রবৃদ্ধি হারে বাড়ে।

কিন্তু…

প্যাটার্ন হলো লেন্স — যে কাঠামো সবসময় ছিল, সেটা দেখতে সাহায্য করে। কিন্তু লেন্স বিকৃতও করে। প্যাটার্ন চিনতে দক্ষ হয়ে গেলে, যেখানে মানায় না সেখানেও সেগুলোর দিকে হাত বাড়াতে শুরু করেন।

“এটা pipeline!”

আসলে এটা শুধু একটা loop।

Event system

যেখানে একটা মেথড কলই যথেষ্ট ছিল।

Driver abstraction

এমন কিছুর জন্য যার ইমপ্লিমেন্টেশন থাকবে মাত্র একটি।

লেখকরা বলেছেন: “আমরা দুজনেই এর সবগুলো করেছি।”

ভুল ১: Premature Abstraction

Driver প্যাটার্ন পড়লেন, আর হঠাৎ আপনার পেমেন্ট ইন্টিগ্রেশনে লাগবে পুরো Manager ক্লাস, একটা Contract, একটা config ফাইল, আর তিনটা driver — অথচ আপনি শুধু Stripe নেন।

আগেভাগেই

interface PaymentGateway { ... }
class PaymentManager extends Manager { ... }
class StripeDriver implements PaymentGateway { ... }
// config/payment.php ...
// আর কোনো driver কখনো এলো না

যথেষ্ট

class StripePayment
{
    public function charge(int $amount, string $token)
    {
        // সরাসরি Stripe
    }
}

নিয়ম

দ্বিতীয় ব্যাকএন্ড আসলে তখনই বুঝবেন abstraction দরকার। তার আগে নয়।

অ্যাপ ছোট থাকলে সাধারণ কোড লেখাই বুদ্ধিমানের কাজ। কখন প্যাটার্ন লাগবে আর কখন সাধারণ কোডেই কাজ হবে — সেটা বুঝতে পারাই সিনিয়র ডেভেলপারের আসল দক্ষতা।

ভুল ২: Control Flow লুকানো

Business logic থেকে side effect আলাদা করতে event অসাধারণ। কিন্তু যখন business logic নিজেই ছয়টা ফাইলে ছড়ানো listener-এ থাকে, তখন একটা পড়ার মতো মেথডের বদলে পেয়েছেন প্রতিক্রিয়ার এক অদৃশ্য চেইন।

OrderPlaced CalculateTax? ApplyDiscount? ChargeCard? 🤷 কোনটা আগে?

নতুন ডেভেলপার জিজ্ঞেস করলো — “অর্ডার প্লেস হলে কী কী হয়?” উত্তরের জন্য গুপ্তধন খোঁজার মতো খুঁজতে হওয়া উচিত নয়।

Event-এ রাখুন

ইমেইল, নোটিফিকেশন, অডিট লগ, search index — স্বাধীন side effect।

সরাসরি কোডে রাখুন

দাম হিসাব, স্টক যাচাই, পেমেন্ট — মূল business flow।

ভুল ৩: পারি বলেই ব্যবহার

সমস্যা চাইছে বলে নয়, পারা যায় বলে lock, retry, rate limiter যোগ করা। এই বইয়ের প্রতিটি প্যাটার্ন জটিলতা যোগ করে:

প্যাটার্নযে দাম দিতে হয়
LockCoordination overhead, TTL নিয়ে ভাবনা
RetryIdempotency নিয়ে ভাবতে হয়
Rate Limiterসঠিক scope ও window বাছতে হয়
FailoverFallback-এর জন্য বাড়তি ইনফ্রা, worker, টেস্ট
EventFlow ট্রেস করা কঠিন
Driverবাড়তি ক্লাস ও indirection

লেখকদের কথা

এগুলো নির্দিষ্ট সমস্যার টুল, ডিফল্ট নয়। যে ডেভেলপারদের আমরা সবচেয়ে সম্মান করি, তারা সবচেয়ে বেশি প্যাটার্ন ব্যবহার করে না। তারা প্যাটার্ন এত ভালো জানে যে বুঝতে পারে কখন ব্যবহার করতে হবে না।

আসল পরামর্শ

নিজের কোডবেসে ফিরে যান, নতুন চোখে দেখুন।

যা ব্যাখ্যা করবে

আগে যেসব জিনিস বিভ্রান্ত করতো, কিছু প্যাটার্ন সেগুলো ব্যাখ্যা করবে।

যা ধরিয়ে দেবে

কিছু প্যাটার্ন এমন বাগ দেখাবে, যা আছে বলে জানতেনই না।

যা সরাতে হবে

কিছু জায়গায় বুঝবেন প্যাটার্নটাই ভুল ছিল — একটা সহজ সমাধান পাশেই পড়ে ছিল।

এই সপ্তাহের চ্যালেঞ্জ

  • আপনার প্রজেক্টের সব external API কল খুঁজুন — কোনটায় Http::retry() দরকার?
  • Multi-server-এ চলে এমন scheduled task-এ withoutOverlapping()->onOneServer() আছে?
  • লগইন ও OTP রুটে throttle আছে?
  • কোনো কন্ট্রোলারে ৩টির বেশি side effect? Event-এ সরানো যায়?
  • এমন কোনো abstraction আছে যার মাত্র একটি ইমপ্লিমেন্টেশন? সরল করা যায়?

আসল দক্ষতা

শুধু প্যাটার্ন দেখা নয় — কখন কোড প্যাটার্ন ছাড়াই ভালো, তা জানা।

এক নজরে সব প্যাটার্ন

প্যাটার্নকোন সমস্যামূল APIকখন নয়
Retryসাময়িক ফেইলিওরHttp::retry(), $tries, retry()Permanent ফেইলিওর
Failoverপ্রাইমারি ডাউন'driver' => 'failover'Lock/rate limit cache-এ
Atomic Lockএকসাথে একাধিক প্রসেসCache::lock(), WithoutOverlappingIdempotent কাজ
Rate Limitঅতিরিক্ত ব্যবহারRateLimiter::for(), throttleনিরাপত্তার একমাত্র স্তর হিসেবে
Pipelineধাপে ধাপে প্রসেসিংPipeline::send()->through()সাধারণ loop-ই যথেষ্ট
EventsSide effect আলাদা করাEvent::dispatch(), ShouldQueueমূল business logic
Driverবদলযোগ্য ব্যাকএন্ডManager, extend()একটিই ইমপ্লিমেন্টেশন
Deferringধীর রেসপন্সdefer(), terminate()ক্রিটিক্যাল কাজ (queue নিন)

প্যাটার্নগুলো কীভাবে জোড়া লাগে

Driver → Failover

সব driver একই contract মানে বলেই failover সম্ভব।

Pipeline → Lock + Rate Limit

Job middleware (pipeline) দিয়েই WithoutOverlapping ও RateLimited লাগে।

Events → Queue → Retry

Queued listener পায় $tries ও backoff।

Lock → Cache Driver

Lock cache layer-এর উপর তৈরি — সঠিক driver (Redis) লাগবে।

লেখক পরিচিতি

Mohammad Emran Hasan

PHP, Laravel ও Symfony নিয়ে ২৫+ বছর প্রোডাকশন সফটওয়্যার বানিয়েছেন। Laravel framework contributor ও Laracon-এর সাবেক স্পিকার। Klasio ও FigLab-এর co-founder ও CEO; AI-assisted engineering নিয়ে কাজ করেন এবং “Agentic Engineering” কোর্স পড়ান।

emranhasan.com · @phpfour

Ahmed Shamim Hasan Shaon

Engineering management ও large-scale system design-এ প্রায় ১০ বছরের অভিজ্ঞতা। Laravel core contributor, ADPList-এ মেন্টর। Kahf-এ Senior Software Engineer; “Think Like a Senior Engineer” কোর্স পড়ান।

ahmedshamim.com · @me_shaon

এই প্রেজেন্টেশন মূল বই Inside Laravel: The Patterns That Power the Framework-এর বাংলা স্টাডি নোট। পূর্ণ বিস্তারিত ও লেখকদের সমর্থনের জন্য মূল বইটি পড়ুন: insidelaravelbook.com