
Day 23 - Domain-Driven Design - কোড যখন Business-এর ভাষায় কথা বলে
আপনার application এখন অনেক বড় হয়েছে। আপনি microservices বা modular monolith নিয়ে কাজ করছেন। সবকিছু ঠিকঠাকই চলছে, কিন্তু নতুন একটা সমস্যা দেখা দিলো।
Spots 

আপনার application এখন অনেক বড় হয়েছে। আপনি microservices বা modular monolith নিয়ে কাজ করছেন। সবকিছু ঠিকঠাকই চলছে, কিন্তু নতুন একটা সমস্যা দেখা দিলো।

Business team মিটিংয়ে বলছে, "যখন কোনো VIP Customer-এর Order confirm হবে, তখন তার Loyalty Points add করতে হবে এবং Inventory থেকে Stock reserve করতে হবে।"
কিন্তু আপনার codebase-এ গিয়ে দেখলেন VIP Customer বা Loyalty Points নামে কিছুই নেই! সেখানে আছে UserEntity, status_flag = 1, আর OrderRepository। Business team-এর ভাষা আর developer-দের কোডের ভাষার মধ্যে বিশাল গ্যাপ। এই গ্যাপের কারণেই complex project-এ bug বেশি আসে এবং requirement বুঝতে ভুল হয়। এই সমস্যার সমাধানই হলো DDD (Domain-Driven Design)। Domain-Driven Design (DDD) কী?
সহজ কথায়, Domain-Driven Design (DDD) হলো সফটওয়্যার তৈরির এমন একটি অ্যাপ্রোচ, যেখানে ডাটাবেস বা ফ্রেমওয়ার্কের চেয়ে Business Domain বা ব্যবসার মূল লজিককে বেশি গুরুত্ব দেওয়া হয়।
সাধারণত আমরা ডাটাবেস টেবিল চিন্তা করে কোড লেখা শুরু করি (Data-Driven)। কিন্তু DDD-তে আমরা আগে Business-এর কাজগুলো (Domain) বুঝি এবং সেই অনুযায়ী কোড সাজাই। এর মূল লক্ষ্য হলো ডেভেলপার এবং ডোমেইন এক্সপার্টদের (business team) মধ্যে দূরত্বের অবসান ঘটানো এবং কোডকে এমনভাবে স্ট্রাকচার করা যেন তা বাস্তব জগতের business process-এর সাথে হুবহু মিলে যায়। Ubiquitous Language: একই ভাষায় কথা বলুন DDD-র প্রথম নিয়ম - developer আর business stakeholder একই শব্দ ব্যবহার করবে।
Business যদি বলে "Order confirm করো", codebase-এও ঠিক order.confirm() মেথড থাকবে। Business যদি বলে "Customer", কোডে User না লিখে Customer লিখতে হবে।
এই common vocabulary-কে বলে Ubiquitous Language। যখন code এবং business একই ভাষায় কথা বলে, তখন requirement implement করা অনেক সহজ হয়ে যায়। Bounded Context: সীমানা টানুন একটা বড় system-এ একই শব্দের মানে ভিন্ন ভিন্ন জায়গায় ভিন্ন হতে পারে। Sales context-এ Customer = নাম, contact, purchase history। Shipping context-এ Customer = delivery address, preferred time। Support context-এ Customer = ticket history, complain log।
এগুলো হলো আলাদা Bounded Context। প্রতিটা context-এ "Customer" একটু আলাদা মডেল। এটা না বুঝলে একটা God-object তৈরি হয় - মানে ২,০০০ লাইনের একটা বিশাল User class যেখানে সব context-এর logic একসাথে ভরা থাকে। Microservices-এ সার্ভিস ভাগ করার ক্ষেত্রে এই Bounded Context-ই সবচেয়ে বড় ভূমিকা পালন করে। Entity vs Value Object: ডেটার ধরন বুঝুন DDD-তে object সাধারণত দুই ধরনের হয়:
১. Entity: যার একটা Unique ID আছে এবং সময়ের সাথে যার state পরিবর্তন হয়। যেমন: Order, Customer। এদের ID এক হলে properties ভিন্ন হলেও এরা একই Entity। ২. Value Object: যার কোনো ID নেই, এর value দিয়েই একে চেনা হয়। যেমন: Address, Money। Value objects সবসময় Immutable হয়। Aggregate: Consistency-র দারোয়ান Aggregate হলো একটা cluster of objects (Entities and Value Objects) যেটা একসাথে consistent থাকতে হবে।
যেমন, Order হলো একটা Aggregate (একে Aggregate Root-ও বলা যায়)। এর ভেতরে OrderItems, ShippingAddress (Value Object) থাকতে পারে। বাইরের কোনো class সরাসরি OrderItem-কে modify করতে পারবে না, যা করার Order-এর মাধ্যমেই করতে হবে। Business rule কোডের ভেতরে থাকবে, Controller বা Service layer-এ নয়। Domain Events: যা ঘটলো সেটা জানাও
আপনার application এখন অনেক বড় হয়েছে। আপনি microservices বা modular monolith নিয়ে কাজ করছেন। সবকিছু ঠিকঠাকই চলছে, কিন্তু নতুন একটা সমস্যা দেখা দিলো।
