paint-brush
ডোমেন-চালিত ডিজাইনের ব্যবহারিক ভূমিকাদ্বারা@tobi
1,576 পড়া
1,576 পড়া

ডোমেন-চালিত ডিজাইনের ব্যবহারিক ভূমিকা

দ্বারা Piotr Tobiasz15m2023/07/22
Read on Terminal Reader
Read this story w/o Javascript

অতিদীর্ঘ; পড়তে

শুরু করার জন্য DDD পরিভাষা, বিল্ডিং ব্লক এবং অন্যান্য ধারণা।
featured image - ডোমেন-চালিত ডিজাইনের ব্যবহারিক ভূমিকা
Piotr Tobiasz HackerNoon profile picture
0-item
1-item

এটি বলা উদ্ভাবনী হওয়া উচিত নয় যে সফ্টওয়্যার লেখা শুধুমাত্র কোড লেখার বিষয়ে নয় - এটি একটি নির্দিষ্ট সমস্যা সমাধানের বিষয়ে। যদিও এটি বিকাশকারীরা যারা শেষ পর্যন্ত সমাধানটি বাস্তবায়ন করে, এটি বিকাশকারী নয় যারা প্রথম স্থানে সমস্যাটি কী তা নির্ধারণ করে। এই কাজটি বিভিন্ন ব্যবসায়িক ব্যক্তিদের দ্বারা পরিচালিত হয়, যারা সমস্যাটি কী, কেন এটি বিদ্যমান এবং কীভাবে এটি সমাধান করা উচিত তা বর্ণনা করার জন্য প্রক্রিয়া, ঝুঁকি এবং ফলাফল বিবেচনা করে। একটি ডোমেন-চালিত প্রেক্ষাপটে, এই ব্যবসায়িক ব্যক্তিদের ডোমেন বিশেষজ্ঞ হিসাবে উল্লেখ করা হয়।


একটি প্রকৌশল দৃষ্টিকোণ থেকে, এটি প্রদর্শিত হয় যে ডোমেন বিশেষজ্ঞদের একটি মূল্যবান সম্পদ রয়েছে: ডোমেন সম্পর্কে তাদের জ্ঞান। যাইহোক, এই জ্ঞান খুব কমই তার কাঁচা আকারে ভাগ করা হয়। পরিবর্তে, এটি সাধারণত প্রয়োজনীয়তার মধ্যে অনুবাদ করা হয় যাতে বিকাশকারীরা এটি বুঝতে এবং প্রয়োগ করতে পারে। এই পদ্ধতির সমস্যা হল যে ব্যবসায়িক ব্যক্তি এবং বিকাশকারীদের ডোমেন জ্ঞান ভিন্ন হতে পারে। এর মানে হল যে যারা সমস্যাটিকে সংজ্ঞায়িত করে এবং যারা এটি সমাধানের জন্য কাজ করে তাদের দৃষ্টিভঙ্গি একত্রিত নাও হতে পারে, যা ভুল বোঝাবুঝি এবং দ্বন্দ্বের দিকে পরিচালিত করে।


তাহলে, উপায় কি? নিশ্চিত করুন যে ব্যবসা এবং প্রযুক্তিগত লোকেরা একই ভাষা এবং পরিভাষা ব্যবহার করে।

ডোমেন-চালিত ডিজাইন কি?

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


DDD কোডে বাস্তব-বিশ্বের ধারণার প্রতিনিধিত্ব করছে এবং এর গঠন সর্বব্যাপী ভাষা চাষ ও ব্যবহার করে, যা ব্যবসায়িক ডোমেনের মডেলিং দ্বারা নির্মিত।


এখনও কিছু পরিভাষা চালু করা বাকি আছে, তাই এটি এখনই 100% পরিষ্কার নাও হতে পারে। সবচেয়ে গুরুত্বপূর্ণ বিষয় হল DDD এমন সরঞ্জাম এবং ক্রিয়াকলাপ সরবরাহ করে যা ব্যবসায়িক দৃষ্টিভঙ্গির সাথে সারিবদ্ধ কোড লেখা এবং কাঠামোগত করার অনুমতি দেয়। এটি তখন কেবল যোগাযোগের বিষয়ে নয় বরং ডিজাইনের সিদ্ধান্ত নেওয়ার বিষয়েও যা আসলে সাধারণ ভাষাকে আকৃতি দেয়।

পরিভাষা

এতে অবাক হওয়ার কিছু নেই যে DDD বিশ্বের সবচেয়ে গুরুত্বপূর্ণ শব্দটি হল ডোমেন ৷ "লার্নিং ডোমেন-চালিত ডিজাইন" এর লেখক ভ্লাদ খনোনভ কীভাবে এটি বর্ণনা করেছেন তা এখানে:


একটি ব্যবসায়িক ডোমেন একটি কোম্পানির কার্যকলাপের প্রধান ক্ষেত্র সংজ্ঞায়িত করে।


এর মানে হল যে ব্যবসার ডোমেনটিকেও বিবেচনা করা যেতে পারে:


  • একটি কোম্পানির আয়ের প্রধান উৎস,
  • কোম্পানিটি কিসের জন্য সবচেয়ে বেশি পরিচিত,
  • কোম্পানী তার প্রতিযোগীদের তুলনায় ভাল করে যে কিছু.


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


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


এটি আরেকটি সমালোচনামূলক তবে সম্ভাব্য অস্পষ্ট শব্দের দিকে নিয়ে যায়: মডেল । এরিক ইভান্স, ডিডিডি সম্পর্কে তার বইতে, মডেলটিকে নিম্নরূপ বর্ণনা করেছেন:


এটি বাস্তবতার একটি ব্যাখ্যা যা হাতে থাকা সমস্যা সমাধানের জন্য প্রাসঙ্গিক দিকগুলিকে বিমূর্ত করে এবং বহিরাগত বিশদ উপেক্ষা করে।


ভ্লাদ খনোনভ এই ধারণাটিকে আরও সম্পর্কযুক্ত শর্তে ব্যাখ্যা করেছেন:


একটি মডেল বাস্তব জগতের একটি অনুলিপি নয়, কিন্তু একটি মানবিক গঠন যা আমাদেরকে বাস্তব-বিশ্বের সিস্টেমগুলি বোঝাতে সাহায্য করে৷


উপসংহারে, একটি মডেল হল একটি ব্যবসায়িক ধারণা বা প্রক্রিয়ার প্রতিনিধিত্ব যা ডোমেনের অন্তর্নিহিত জটিলতা বোঝা এবং যোগাযোগের সুবিধা দেয়।


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


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


ডোমেন-চালিত ডিজাইন (DDD) পরিভাষা ধাঁধার শেষ অংশটি হল সর্বব্যাপী ভাষা। এটি একটি প্রকল্পে প্রযুক্তিগত এবং ব্যবসায়িক স্টেকহোল্ডার উভয়ের দ্বারা ব্যবহৃত ভাগ করা ভাষাকে বোঝায়। ডোমেন মডেল থেকে প্রাপ্ত ব্যবসার ডোমেন বর্ণনা করার জন্য একটি সাধারণ ভাষা থাকা DDD-তে অত্যন্ত গুরুত্বপূর্ণ। এটি নিশ্চিত করতে সাহায্য করে যে সমস্ত দলের সদস্যদের সমস্যা স্থান, এর ধারণা এবং তাদের সম্পর্ক সম্পর্কে একটি স্পষ্ট বোঝা রয়েছে। এটি আরও ভাল প্রান্তিককরণের দিকে পরিচালিত করে এবং ভুল বোঝাবুঝির ঝুঁকি হ্রাস করে। সর্বব্যাপী ভাষা ব্যবহার করে, সফ্টওয়্যার সমাধান সঠিকভাবে অন্তর্নিহিত ব্যবসায়ের প্রয়োজনীয়তাগুলিকে প্রতিফলিত করতে পারে, এটিকে DDD-এর একটি গুরুত্বপূর্ণ উপাদান করে তোলে।


বেশিরভাগ পরিভাষা কভার করার সাথে, ডোমেন-চালিত নকশা কী তা বোঝা সহজ হওয়া উচিত। এখন সময় এসেছে প্রকৃত কীভাবে - DDD-এর বিল্ডিং ব্লকগুলি সম্পর্কে অনুসন্ধান করার।

বিল্ডিং ব্লক

DDD বিল্ডিং ব্লক একটি কার্যকর এবং দক্ষ ডোমেন মডেল তৈরির ভিত্তি হিসেবে কাজ করে। ভ্লাদ খনোনভ নিম্নলিখিত উপায়ে ডোমেন মডেলকে সংজ্ঞায়িত করেছেন:


একটি ডোমেন মডেল ডোমেনের একটি অবজেক্ট মডেল যা আচরণ এবং ডেটা উভয়ই অন্তর্ভুক্ত করে।


ডোমেন মডেল বিভিন্ন বিল্ডিং ব্লক এবং কাঠামো নিয়ে গঠিত। সবচেয়ে গুরুত্বপূর্ণ হল:


  • মূল্যবান বস্তু,
  • সত্তা,
  • সমষ্টি,
  • ডোমেন ইভেন্ট,
  • ভান্ডার,
  • ডোমেন পরিষেবা।

মান অবজেক্ট

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


  • আর্থিক পরিমাণ,
  • তারিখের পরিসীমা,
  • ডাক ঠিকানা.


পাইথনে একটি সাধারণ মান অবজেক্ট কীভাবে প্রয়োগ করা যেতে পারে তা এখানে:


 from pydantic import BaseModel class Address(BaseModel):  """Customer address."""  country: str  city: str  street: str  house_number: str  class Config:    frozen = True


এর মানে হল যে দুটি ঠিকানার তুলনা করার জন্য সমতা অপারেটর ( == ) ব্যবহার করে শুধুমাত্র তখনই True ফিরে আসবে যখন উভয় বস্তুর ঠিক একই মান বরাদ্দ করা থাকে।

সত্তা

সত্তা হল পরবর্তী ধরনের বিল্ডিং ব্লক। সত্তাগুলি ডোমেনের মধ্যে স্বতন্ত্র বস্তুগুলিকে একটি স্বতন্ত্র পরিচয় সহ প্রতিনিধিত্ব করে, যেমন একজন ব্যক্তি বা একটি আদেশ৷ এগুলি মান অবজেক্টের মতো যেভাবে তারা ডেটা সঞ্চয় করে, তবে তাদের বৈশিষ্ট্যগুলি পরিবর্তন করতে পারে এবং প্রত্যাশিত, এবং এইভাবে তাদের একটি অনন্য শনাক্তকারীর প্রয়োজন৷ আদেশ এবং ব্যক্তিগত তথ্য সত্তার দুটি সহজ উদাহরণ:


 import uuid from pydantic import BaseModel, Field from practical_ddd.building_blocks.value_objects import Address class Person(BaseModel):  """Personal data."""  id: uuid.UUID = Field(default_factory=uuid.uuid4)  first_name: str  last_name: str  address: Address class Order(BaseModel):  """Customer order."""  id: uuid.UUID = Field(default_factory=uuid.uuid4)  description: str  value: float


যেহেতু দৃষ্টান্তের মান উভয় ক্ষেত্রেই পরিবর্তনযোগ্য, তাদের একটি সনাক্তকরণ প্রয়োজন, যা একটি UUID হতে পারে। আরও গুরুত্বপূর্ণ বিষয় হল, বেশিরভাগ ক্ষেত্রে, সত্তাগুলিকে সরাসরি পরিচালনা করার জন্য নয় বরং একটি সমষ্টির মাধ্যমে।

সমষ্টি

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


পূর্ববর্তী উদাহরণ থেকে অনুসরণ করে, একটি সমষ্টিকে গ্রাহক হিসাবে উপস্থাপন করা যেতে পারে:


 import uuid from pydantic import BaseModel, Field from practical_ddd.building_blocks.entities import Person, Order from practical_ddd.building_blocks.value_objects import Address class Customer(BaseModel):  """Customer aggregate.  Manages personal information as well as orders.  """  id: uuid.UUID = Field(default_factory=uuid.uuid4)  person: Person  orders: list[Order] = Field(default_factory=list)  def change_address(self, new_address: Address) -> None:    self.person.address = new_address  def add_order(self, order: Order) -> None:    if self.total_value + order.value > 10000:      raise ValueError("Order cannot have value higher than 10000")    self.orders.append(order)  def remove_order(self, order_id: uuid.UUID) -> None:    order = next((order for order in self.orders if order.id == order_id), None)    if order is None:      raise IndexError("Order not found")    self.orders.remove(order)  @property  def total_value(self) -> float:    return sum(order.value for order in self.orders)


গ্রাহক সরাসরি ব্যক্তিগত ডেটার সাথে সংযুক্ত থাকে এবং এটি সমস্ত অর্ডার সংরক্ষণ করে। সর্বোপরি, সামগ্রিকভাবে ব্যক্তির ঠিকানা পরিচালনার পাশাপাশি অর্ডার যোগ এবং অপসারণের জন্য একটি ইন্টারফেস প্রকাশ করে। এটি এই কারণে যে সমষ্টির অবস্থা শুধুমাত্র সংশ্লিষ্ট পদ্ধতিগুলি সম্পাদন করে পরিবর্তন করা যেতে পারে।


যদিও পূর্ববর্তী উদাহরণটি তুলনামূলকভাবে সহজবোধ্য, শুধুমাত্র একটি সীমাবদ্ধতার সাথে (অর্ডার মান 10000 এর বেশি হতে পারে না), এটি ডিডিডি বিল্ডিং ব্লক এবং তাদের সম্পর্কগুলির ব্যবহার প্রদর্শন করা উচিত। প্রকৃত সিস্টেমে, সমষ্টিগুলি প্রায়শই আরও জটিল, আরও সীমাবদ্ধতা, সীমানা এবং সম্ভবত আরও সম্পর্ক সহ। সব পরে, তাদের খুব অস্তিত্ব এই জটিলতা পরিচালনা করা হয়. উপরন্তু, বাস্তব জগতে, সমষ্টি সাধারণত একটি ডাটা স্টোর, যেমন একটি ডাটাবেসের মধ্যে টিকে থাকে। এখানেই সংগ্রহস্থলের প্যাটার্নটি কার্যকর হয়।

ভান্ডার

সামগ্রিক অবস্থার পরিবর্তনগুলি একটি একক পারমাণবিক অপারেশনে লেনদেনমূলকভাবে প্রতিশ্রুতিবদ্ধ হওয়া উচিত। যাইহোক, "নিজেকে টিকে থাকা" সামগ্রিকের দায়িত্ব নয়। রিপোজিটরি প্যাটার্ন ডেটা স্টোরেজ এবং পুনরুদ্ধারের বিবরণকে বিমূর্ত করতে দেয় এবং পরিবর্তে, বিমূর্ততার উচ্চ স্তরে সমষ্টির সাথে কাজ করে। সহজভাবে বলতে গেলে, একটি সংগ্রহস্থলকে সমষ্টি এবং ডেটা স্টোরেজের মধ্যে একটি স্তর হিসাবে বিবেচনা করা যেতে পারে। একটি JSON ফাইল একটি মোটামুটি। এই ধরনের একটি দোকানের সহজ উদাহরণ। গ্রাহক সমষ্টির একটি সংগ্রহস্থল থাকতে পারে যা JSON ফাইলগুলিতে কাজ করে:


 import json import uuid from practical_ddd.building_blocks.aggregates import Customer class CustomerJSONRepository:  """Customer repository operating on JSON files."""  def __init__(self, path: str) -> None:    self.path = path  def get(self, customer_id: uuid.UUID) -> Customer:    with open(self.path, "r") as file:      database = json.load(file)      customer = database["customers"].get(str(customer_id))      if customer is None:        raise IndexError("Customer not found")      person = database["persons"][str(customer["person"])]      orders = [database["orders"][order_id] for order_id in customer["orders"]]    return Customer(      id=customer["id"],      person=person,      orders=orders,    )  def save(self, customer: Customer) -> None:    with open(self.path, "r+") as file:      database = json.load(file)      # Save customer      database["customers"][str(customer.id)] = {        "id": customer.id,        "person": customer.person.id,        "orders": [o.id for o in customer.orders],      }      # Save person      database["persons"][str(customer.person.id)] = customer.person.dict()      # Save orders      for order in customer.orders:        database["orders"][str(order.id)] = order.dict()      file.seek(0)      json.dump(database, file, indent=4, default=str)


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

ডোমেন পরিষেবা

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


 import uuid from typing import Protocol from practical_ddd.building_blocks.aggregates import Customer class CustomerRepository(Protocol):  """Customer repository interface."""  def get(self, customer_id: uuid.UUID) -> Customer:    ...  def save(self, customer: Customer) -> None:    ... class CustomerService:  """Customer service."""  def __init__(self, repository: CustomerRepository) -> None:    self.repository = repository  def get_customer(self, customer_id: uuid.UUID) -> Customer | None:    try:      return self.repository.get(customer_id)    except IndexError:      return None  def save_customer(self, customer: Customer) -> None:    existing_customer = self.get_customer(customer.id)    # If customer is already in the database and has more than 2 orders,    # he cannot end up with half of them after a single save.    if (      existing_customer is not None      and len(existing_customer.orders) > 2      and len(customer.orders) < (len(existing_customer.orders) / 2)    ):      raise ValueError(        "Customer cannot lose more than half of his orders upon single save!"      )    self.repository.save(customer)


Aggregate নিশ্চিত করতে পারে না যে কীভাবে এটির অবস্থা JSON ফাইলের থেকে আলাদা কারণ এটির প্রথম স্থানে JSON ফাইল সম্পর্কে কোনো জ্ঞান নেই। সেজন্য ডোমেইন সার্ভিসে তুলনামূলক যুক্তি অবশ্যই অন্তর্ভুক্ত করতে হবে। এটাও মনে রাখা গুরুত্বপূর্ণ যে ডোমেন সার্ভিস রিপোজিটরি অ্যাবস্ট্রাকশনের সাথে কাজ করবে। এটি নির্ভরতা ইনজেকশন ব্যবহার করে একটি বিকল্পের সাথে কংক্রিট বাস্তবায়নকে অদলবদল করা সহজ করে তোলে।

সবগুলোকে একত্রে রাখ

সমস্ত টুকরা এখন আচ্ছাদিত করা হয়েছে, তারা এখন একটি কর্ম প্রোগ্রাম হিসাবে দেখা যেতে পারে:


 import uuid from practical_ddd.building_blocks import aggregates, entities, value_objects from practical_ddd.database.repository import CustomerJSONRepository from practical_ddd.service import CustomerService # Initialize domain service with json repository srv = CustomerService(repository=CustomerJSONRepository("test.json")) # Create a new customer customer = aggregates.Customer(  person=entities.Person(    first_name="Peter",    last_name="Tobias",    address=value_objects.Address(      country="Germany",      city="Berlin",      street="Postdamer Platz",      house_number="2/3",    ),  ), ) srv.save_customer(customer) # Add orders to existing customer customer = srv.get_customer(uuid.UUID("a32dd73a-6c1b-4581-b1d3-2a1247320938")) assert customer is not None customer.add_order(entities.Order(description="Order 1", value=10)) customer.add_order(entities.Order(description="Order 2", value=210)) customer.add_order(entities.Order(description="Order 3", value=3210)) srv.save_customer(customer) # Remove orders from existing customer # If there are only 3 orders, it's gonna fail customer = srv.get_customer(uuid.UUID("a32dd73a-6c1b-4581-b1d3-2a1247320938")) assert customer is not None customer.remove_order(uuid.UUID("0f3c0a7f-67fd-4309-8ca2-d007ac003b69")) customer.remove_order(uuid.UUID("a4fd7648-4ea3-414a-a344-56082e00d2f9")) srv.save_customer(customer)


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

সারসংক্ষেপ

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

আফটারওয়ার্ড এবং পরবর্তী পদক্ষেপ

এই নিবন্ধটি কখনই "DDD: জিরো থেকে হিরো" এর মত কিছু হওয়ার উদ্দেশ্য ছিল না, বরং DDD মহাবিশ্বের একটি ভূমিকা হিসাবে পরিবেশন করা। আমি ডোমেন-চালিত ডিজাইনের সবচেয়ে গুরুত্বপূর্ণ ধারণাগুলিকে খুব সহজবোধ্য এবং ব্যবহারিক পদ্ধতিতে প্রদর্শন করতে চেয়েছিলাম। আমি বিশ্বাস করি যে ডোমেন-চালিত ডিজাইন শেখা প্রোগ্রামিং দক্ষতা বাড়ানোর একটি চমৎকার উপায়। যাইহোক, আপনি এটি সম্পর্কে প্রায়শই শুনতে পান না - অন্তত "11 INSANE JavaScript টিপস এবং কৌশল - একটি থ্রেড 🧵" এর মতো নয়।


যাই হোক না কেন, আপনি যদি এইগুলির মধ্যে যেকোনও আকর্ষণীয় খুঁজে পান, আপনি বই এবং নিবন্ধগুলির জন্য উত্স বিভাগের মাধ্যমে দেখতে পারেন যা আমাকে প্রথম স্থানে এই নিবন্ধটি লিখতে অনুপ্রাণিত করেছিল। কিছু ধারণা আছে যা আমি কভার করিনি কারণ আমি ভেবেছিলাম যে সেগুলি এই ভূমিকার সুযোগের বাইরে ছিল, কিন্তু সেগুলি তদন্ত করার উপযুক্ত:


  • আবদ্ধ প্রসঙ্গ
  • ডোমেন ইভেন্ট
  • ইভেন্ট স্টর্মিং


আপনি নিঃসন্দেহে নীচে তালিকাভুক্ত উত্সগুলিতে তাদের খুঁজে পাবেন।

সূত্র

নিবন্ধে ব্যবহৃত কোড উদাহরণ এখানে পাওয়া যাবে: লিঙ্ক


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


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


Przemysław Górecki দ্বারা পাইথনে DDD । আমি নিবন্ধটি লেখার শেষের কাছাকাছি এই ব্লগটি আবিষ্কার করেছি, কিন্তু এটি আমার আগ্রহকে বাড়িয়ে তুলেছে কারণ এটি কতটা পেশাদার। মজার ঘটনা: আমি প্রজেমিস্লোর মতো একই কোম্পানিতে কাজ করেছি, এবং আমি এটি সম্পর্কে সম্পূর্ণ অজ্ঞাত ছিলাম।


এছাড়াও এখানে প্রকাশিত.