উপসংহার
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-এ থাকে, তখন একটা পড়ার মতো মেথডের বদলে পেয়েছেন প্রতিক্রিয়ার এক অদৃশ্য চেইন।
নতুন ডেভেলপার জিজ্ঞেস করলো — “অর্ডার প্লেস হলে কী কী হয়?” উত্তরের জন্য গুপ্তধন খোঁজার মতো খুঁজতে হওয়া উচিত নয়।
Event-এ রাখুন
ইমেইল, নোটিফিকেশন, অডিট লগ, search index — স্বাধীন side effect।
সরাসরি কোডে রাখুন
দাম হিসাব, স্টক যাচাই, পেমেন্ট — মূল business flow।
ভুল ৩: পারি বলেই ব্যবহার
সমস্যা চাইছে বলে নয়, পারা যায় বলে lock, retry, rate limiter যোগ করা। এই বইয়ের প্রতিটি প্যাটার্ন জটিলতা যোগ করে:
| প্যাটার্ন | যে দাম দিতে হয় |
|---|---|
| Lock | Coordination overhead, TTL নিয়ে ভাবনা |
| Retry | Idempotency নিয়ে ভাবতে হয় |
| Rate Limiter | সঠিক scope ও window বাছতে হয় |
| Failover | Fallback-এর জন্য বাড়তি ইনফ্রা, worker, টেস্ট |
| Event | Flow ট্রেস করা কঠিন |
| 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(), WithoutOverlapping | Idempotent কাজ |
| Rate Limit | অতিরিক্ত ব্যবহার | RateLimiter::for(), throttle | নিরাপত্তার একমাত্র স্তর হিসেবে |
| Pipeline | ধাপে ধাপে প্রসেসিং | Pipeline::send()->through() | সাধারণ loop-ই যথেষ্ট |
| Events | Side 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