ბიბლიოთეკა
00/07 · ~36 წთ
GUIDEDECK · სისტემის დიზაინი ბიზნესის გარშემო

Domain-Driven
Design & მოდელი
მის ცენტრში.

36-წუთიანი სამუშაო სესია რთული ბიზნეს-სისტემების მოთვინიერებაზე — საერთო ენიდან და შემოსაზღვრული კონტექსტებიდან, აგრეგატებისა და დომენის მოვლენების გავლით, სტრატეგიულ გადაწყვეტილებამდე: როდის ღირს DDD და როდის იმარჯვებს ჩუმად ჩვეულებრივი CRUD აპლიკაცია.

~36 წთდამწყები → საშუალოენისგან დამოუკიდებელი
გადაახვიეთ
01 · რატომ მნიშვნელოვანია 4 წთ

რთული კოდი არ არის —
რთული ბიზნესია, რომელსაც კოდი მოდელირებს.

სისტემების უმეტესობა დატვირთვისგან არ იშლება; ისინი გაუგებრობისგან იშლება. გუნდი წელიწადი სწრაფად უშვებს ფუნქციონალს, შემდეგ კი ყოველი ცვლილება სამ ისეთ რამეს ამტვრევს, რომლებსაც ერთმანეთთან არავინ აკავშირებდა. ძირეული მიზეზი თითქმის ყოველთვის ერთია: კოდმა შეწყვიტა იმის ასახვა, როგორ მუშაობს ბიზნესი სინამდვილეში. DDD ინსტრუმენტების ნაკრებია, რომელიც ამ ორს სინქრონში ინარჩუნებს.

DDD — Domain-Driven Design — მიდგომაა, სადაც კოდის სტრუქტურა და ენა ასახავს ბიზნეს-დომენს, რომელსაც ის ემსახურება. დომენი არის ამოცანა, რომელსაც წყვეტთ (დაკრედიტება, ლოგისტიკა, ბილეთების გაყიდვა); მოდელი კი მისი გამარტივებული, შეთანხმებული სურათია, რომელიც თქვენს კოდში ცხოვრობს. DDD არის აზროვნებისა და თანამშრომლობის წესი, და არა ფრეიმვორკი, რომელსაც აინსტალირებთ.

სირთულის ორი სახე

  • არსებითი — თავად ბიზნესის ნამდვილი არეულობა: დაზღვევის, გადაზიდვის ან ხელფასების წესები, სასაზღვრო შემთხვევები და ლექსიკა. ამას კოდით ვერ გააქრობთ; შეგიძლიათ მხოლოდ ნათლად დაამოდელიროთ.
  • შემთხვევითი — სირთულე, რომელსაც ჩვენ ვამატებთ: ფრეიმვორკები, წებო, ჭკვიანური აბსტრაქციები, აწეწილი შრეები. ეს თქვენს კონტროლშია.
  • DDD ძალისხმევას არსებით სირთულეზე მიმართავს — მოდელის სწორად აგებაზე — და არა შემთხვევითი მილსადენების გაპრიალებაზე.
ერთს ცვლი → ყველას ეძებ
ერთს ცვლი → ერთ ადგილას
UI · წესი
კონტროლერი
დომენის მოდელი
წესები აქ ცხოვრობს
SQL · წესი
job · წესი
ტრიგერი
დამხმარე
წესები მიმოფანტული · მყიფე
ერთი მოდელი · ნათელი

როცა წესები მიმოიფანტება, ყოველი ცვლილება ძებნაა. DDD ბიზნეს-ლოგიკას ერთ, კარგად დასახელებულ მოდელში კრებს.

სიმპტომი

დეველოპერები და ბიზნესი ერთსა და იმავე რამეს სხვადასხვა სიტყვით უწოდებენ — კოდში „user“, შეხვედრაზე „დაზღვეული“. თარგმანის შეცდომები ჩუმად გროვდება.

ღირებულება

ლოგიკა კონტროლერებზე, შეკითხვებსა და ტრიგერებზე იფანტება. ახალი ადამიანის ჩართვას თვეები სჭირდება; პატარა ცვლილებებიც სახიფათოდ გამოიყურება.

ფსონი

ჩადეთ საერთო მოდელსა და ენაში თავიდანვე. ეს მხოლოდ მაშინ ამართლებს, როცა დომენი მართლაც რთულია — ესაა ის პატიოსანი დათქმა, რომელსაც მე-7 ნაწილში დავუბრუნდებით.

02 · საერთო ენა და დომენის მოდელი 5 წთ

ერთი ენა, რომელზეც
ექსპერტებიც ლაპარაკობენ და კოდიც.

DDD-ის ყველაზე დიდი ეფექტის მქონე იდეა დაწყებისას არაფერი ჯდება: შეთანხმდით სიტყვებზე. როცა დომენის ექსპერტი ამბობს „ფასის შეთავაზებას ვადა ეწურება“, კოდში Quote-ს უნდა ჰქონდეს expire() მეთოდი — და არა status ფლაგი, რომელსაც update-ჰენდლერი ცვლის. ერთი სიტყვა, ერთი ცნება, ყველგან.

საერთო ენა — საერთო, მკაცრად შეთანხმებული ლექსიკა, რომელსაც დეველოპერები და დომენის ექსპერტები ერთად აგებენ და ერთნაირად იყენებენ საუბარში, დიაგრამებსა და კოდში. არანაირი ჩუმი მთარგმნელი შრე „რაც ბიზნესმა თქვა“-სა და „როგორ დავარქვით კლასს“-ს შორის. თუ ტერმინი შეხვედრაზე შეიცვალა, კლასსაც ეცვლება სახელი.
ექსპერტი
დაზღვეული
დეველოპერი
user_row
დაზღვეული
იგივე სიტყვა კოდში
ექსპერტი
დეველოპერი
გარეშე · დანაკარგიანი თარგმანი
მასთან · ერთი ტერმინი
თარგმანი არაა = დრიფტი არაა

ბიზნესსა და კოდს შორის ყოველი ჩუმი თარგმანი ადგილია, სადაც ბაგები და გაუგებრობები მრავლდება. საერთო ტერმინი ამ ნაპრალს აქრობს.

რა არის დომენის მოდელი სინამდვილეში

  • არც მონაცემთა ბაზის სქემა და არც კედელზე დახატული დიაგრამა — ეს არის ცნებებისა და წესების ნაკრები, კოდში გამოხატული, რომელიც გუნდის შეთანხმებით ბიზნესს წარმოადგენს.
  • ის განზრახ გამარტივებულია: მოდელი ინახავს იმას, რაც ამოცანისთვის მნიშვნელოვანია, დანარჩენს კი ტოვებს. რუკა ტერიტორია არ არის.
  • ის ჩვეულებრივ ობიექტზე ორიენტირებულ მოდელირებას ეყრდნობა — კლასებს, რომლებიც მონაცემებს იმ ქცევასთან აერთიანებენ, რომელიც მათ იცავს.
ანემიური მოდელი — წესების გარეშე
class Order { status: string; lines: Line[] }  // just a bag of fields

// rules live elsewhere, scattered and unguarded:
function ship(o: Order) {
  if (o.status !== "paid") throw Error("not paid")
  o.status = "shipped"     // anyone, anywhere, can flip this
}
მდიდარი მოდელი — წესები მონაცემებთან
class Order {
  private status = "pending"
  ship() {                       // the behavior IS the language
    if (this.status !== "paid")
      throw new Error("cannot ship an unpaid order")
    this.status = "shipped"
  }
}
// invalid transitions are impossible from outside

ჰგავს  გლოსარს, რომელსაც მთელი გუნდი ხელს აწერს: როცა ყველა — გაყიდვები, მხარდაჭერა, ინჟინერია — „გაგზავნილში“ ზუსტად ერთსა და იმავეს გულისხმობს, კამათი სიტყვებზე წყდება და საქმეზე იწყება.

03 · შემოსაზღვრული კონტექსტები და რუკა 6 წთ

ერთი მოდელი ყველაფერს ვერ ნიშნავს.
შემოხაზეთ მას საზღვრები.

სცადეთ, ერთმა Customer კლასმა ერთდროულად გაყიდვებს, მხარდაჭერასა და ბილინგს მოემსახუროს და მიიღებთ ორმოცველიან მონსტრს, რომელიც სამივესთვის არასწორია. გამოსავალი უფრო დიდი მოდელი არ არის — რამდენიმე უფრო პატარაა, თითოეული სწორია საკუთარ საზღვრებში. სიტყვას მხოლოდ ერთი მნიშვნელობა აქვს თითო კონტექსტში.

შემოსაზღვრული კონტექსტი — ცხადი საზღვარი, რომლის შიგნითაც კონკრეტული დომენის მოდელი და მისი საერთო ენა თანმიმდევრული და ცალსახაა. ერთი და იგივე სიტყვა სხვადასხვა კონტექსტში სხვადასხვას ნიშნავს — და ეს კარგია, სანამ თითოეული კონტექსტი საკუთარ მოდელს ფლობს და საზღვარზე თარგმნიან.
გაყიდვები
Customer = · · Lead პაიპლაინით · · შეთავაზებები, ალბათობა · · გადახდის მონაცემები არა · ფლობს: Lead, Quote
მხარდაჭერა
Customer = · · Account თიქეთებით · · SLA, ისტორია · · პაიპლაინი არა · ფლობს: Ticket, SLA
ბილინგი
Customer = · · Payer ინვოისებით · · საგადასახადო id, პირობები · · თიქეთები არა · ფლობს: Invoice, Payment
ერთი სიტყვა · სამი კონტექსტი · სამი მოდელი

„Customer“ თითოეულ კონტექსტში სხვა მოდელია. მათი ერთ საერთო კლასში ჩატენვა კლასიკური შეცდომაა.

კონტექსტების რუკა

როცა რამდენიმე კონტექსტი გაქვთ, ხატავთ, როგორ უკავშირდებიან ისინი ერთმანეთს. კონტექსტების რუკა თქვენი კონტექსტების ზოგადი დიაგრამაა და თითოეულ საზღვარზე არსებული ინტეგრაციის ურთიერთობა — ვინ ვისზეა დამოკიდებული და ვინ თარგმნის.

აქ ხვდება DDD სისტემურ არქიტექტურას: შემოსაზღვრული კონტექსტი ბუნებრივი ნაკერია, რომლის გასწვრივაც სერვისი იყოფა. ამ დაყოფის მექანიკა აქაა: არქიტექტურული პატერნები & სტილები.

კონტექსტების რუკა: გაყიდვები მხარდაჭერისა და ბილინგის upstream-ია. იდენტობა საერთო ბირთვია, რომელზეც ორივე დამოკიდებულია.

ინტეგრაციის ურთიერთობები

P
პარტნიორობა / საერთო ბირთვი
ორი კონტექსტი ერთად იმარჯვებს ან ერთად ეცემა.
+

პარტნიორობა — ორი გუნდი მჭიდროდ კოორდინირდება და კონტექსტებს ერთი ნაბიჯით ავითარებს. საერთო ბირთვი — ისინი მოდელის პატარა, ერთობლივად ფლობილ ნაწილს იზიარებენ (მაგ. საერთო Money ან UserId). ძლიერია, მაგრამ ძვირი: ყოველ ცვლილებაზე ორივე გუნდი უნდა შეთანხმდეს, ამიტომ საერთო ნაწილი პატარა შეინახეთ.

C
მყიდველი / მომწოდებელი
downstream-ს რეალური ხმა აქვს upstream-თან.
+

upstream კონტექსტი აწვდის იმას, რაც downstream-ს სჭირდება (გაყიდვები კვებავს ბილინგს). ეს ჯანსაღი ურთიერთობაა, როცა downstream გუნდის საჭიროებები მოლაპარაკებით ხვდება upstream გუნდის backlog-ში — მომწოდებელი ემსახურება მყიდველს.

F
კონფორმისტი
downstream უბრალოდ იღებს upstream-ის მოდელს.
+

როცა upstream არ იხრება — გადახდების პროცესორი, გიგანტური შიდა პლატფორმა — downstream უბრალოდ ეთანხმება მის მოდელს. იაფი და პრაგმატულია, მაგრამ მემკვიდრეობით იღებთ მათ ენას და მათ უცნაურობებს. კარგია ზოგადი საკითხებისთვის; სახიფათოა თქვენი ძირითადი დომენისთვის.

A
დამცავი შრე (ACL)
თარგმნეთ საზღვარზე, რომ თქვენი მოდელი დაიცვათ.
+

როცა არეულ ან უცხო მოდელთან ინტეგრაცია გიწევთ, მაგრამ უარს ამბობთ, რომ ის შემოგეპაროთ, აგებთ დამცავ შრეს (anti-corruption layer) — თარგმანის საზღვარს, რომელიც მათ ცნებებს თქვენსად აქცევს. მე-6 ნაწილში მას რეალურ კოდს დავუწერთ; ესაა DDD-ის ყველაზე ღირებული თავდაცვითი პატერნი.

04 · აგრეგატები, ენტითები და value object-ები 6 წთ

სამშენებლო ბლოკები, რომლებიც
მოდელს თანმიმდევრულს ხდიან.

შემოსაზღვრული კონტექსტის შიგნით მოდელი სამი სახის ობიექტისგან შედგება. სწორად გაარჩიეთ ისინი და თქვენი ინვარიანტები — წესები, რომლებიც ყოველთვის უნდა სრულდებოდეს — თავად დაიცავენ თავს. არასწორად გაარჩიეთ და უკან ბრუნდებით მიმოფანტულ ვალიდაციასა და დაზიანებულ მონაცემებთან.

ენტითი

განისაზღვრება იდენტობით

აქვს უნიკალური id, რომელიც ცვლილებების მიღმაც რჩება. ორი შეკვეთა იდენტური შიგთავსით მაინც სხვადასხვა შეკვეთაა. მაგალითად Order, Customer, Shipment.

value object

განისაზღვრება მნიშვნელობებით

არავითარი იდენტობა, უცვლელი, ურთიერთშენაცვლებადი. ორი Money(5, "USD") ტოლი და ურთიერთშენაცვლებადია. მაგალითად Money, Address, DateRange.

აგრეგატი

თანმიმდევრულობის საზღვარი

ენტითებისა და value object-ების კლასტერი, რომელსაც ერთ ერთეულად უყურებენ და რომელშიც ერთადერთი შესასვლელი მისი ფესვია. მის შიგნით წესები ერთად რჩება ძალაში.

// VALUE OBJECT — equal by value, immutable
class Money {
  constructor(readonly amount: number,
              readonly currency: string) {}
  add(o: Money): Money {        // returns a NEW one
    return new Money(this.amount + o.amount, this.currency)
  }
}
// ENTITY — equal by identity, mutable over time
class Order { constructor(readonly id: OrderId) {} }
Order აგრეგატი
Order · ფესვი
Customer
OrderLine
OrderLine
Money · value object
შესვლა მხოლოდ ფესვით
id-ით, არა ref-ით

გარე კოდი მხოლოდ ფესვს ესაუბრება. ხაზები და Money შიგნით არის დაცული; სხვა აგრეგატებზე მითითება id-ით ხდება და არა პირდაპირი შენახვით.

აგრეგატის ფესვის საქმე

  • ის ერთადერთი შესასვლელია. მას გვერდს ვერასდროს აუვლით, რომ შვილობილ ობიექტს მისწვდეთ — სწორედ ასე ცოცხლობს ინვარიანტები.
  • ის მთელ თავის კლასტერზე ატარებს წესებს: „შეკვეთის ჯამი მისი ხაზების ჯამს უნდა უდრიდეს“ მხოლოდ მაშინაა გარანტირებული, თუ ხაზები ფესვის გავლით იცვლება.
  • ის არის შენახვისა და ტრანზაქციების ერთეული — მთელ აგრეგატს ერთბაშად ტვირთავთ და ინახავთ (ნაწილი 6).

აგრეგატები პატარა შეინახეთ

  • დამწყებთა ხშირი შეცდომაა ერთი გიგანტური აგრეგატი, რომელიც დომენის ნახევარს იტევს. ის ლოკებზე კონკურენციისა და წარმადობის კოშმარად იქცევა.
  • მარტივი წესი: აგრეგატი მხოლოდ იმას უნდა იტევდეს, რაც ერთსა და იმავე მომენტში უნდა იყოს თანმიმდევრული. დანარჩენზე მითითება id-ით ხდება, შეთანხმება კი — მოვლენების გავლით.
  • აგრეგატებს შორის მიიღებთ საბოლოო თანმიმდევრულობას — და ეს ჩვეულებრივ ნორმალურია.

ჰგავს  საყიდლების კალათას: ნივთებს ამატებთ და შლით კალათის გავლით და არა უცხო ხაზის პირდაპირი რედაქტირებით. კალათა ფესვია; ის ინახავს ჯამს პატიოსნად.

05 · მოვლენები და event storming 5 წთ

დააფიქსირეთ, რაც მოხდა,
და მოდელს რეაქცია მიეცით.

ბიზნესი მოვლენებით აზროვნებს: შეკვეთა განთავსდა, გადახდა მიღებულ იქნა, გზავნილი გაიგზავნა. ამ ფაქტების პირველხარისხოვნად ქცევა მოდელში — როგორც დომენის მოვლენების — აგრეგატებს პატარას ინარჩუნებს და კონტექსტებს სუსტად დაკავშირებულს, რადგან რეაქციები იმ აგრეგატიდან გადის, რომელმაც ისინი გამოიწვია.

დომენის მოვლენა — ჩანაწერი იმისა, რაც დომენში მნიშვნელოვანი მოხდა, წარსულ დროში დასახელებული და უცვლელი მას შემდეგ, რაც მოხდა (OrderPlaced, PaymentReceived). ცვლილების მფლობელი აგრეგატი მას იწერს; სისტემის სხვა ნაწილები ეწერებიან და რეაგირებენ — ხშირად სხვა შემოსაზღვრულ კონტექსტში.
// a fact: past tense, immutable, named in the language
class OrderPlaced {
  constructor(
    readonly orderId: OrderId,
    readonly placedAt: Date,
  ) {}
}
// the aggregate root records it as part of placing:
order.place()            // → emits OrderPlaced
// Billing, Email, Analytics each react on their own.

აგრეგატი ფაქტს იწერს; გამომწერები დამოუკიდებლად რეაგირებენ. ტრანსპორტი — ბროკერი — ცალკე საკითხია.

დომენის მოვლენები მოდელირების იდეაა; ის, თუ როგორ მოძრაობენ ისინი სერვისებს შორის — ბროკერები, დანაწილებები, მიწოდების გარანტიები — შეტყობინებების რიგებისა & ნაკადების თემაა. ერთი პროცესის შიგნით დომენის მოვლენა უბრალოდ მეხსიერებაში არსებული შეტყობინებაც შეიძლება იყოს.

Event storming

Event storming სწრაფი, დაბალტექნოლოგიური ვორქშოპია: შეკრიბეთ დომენის ექსპერტები და დეველოპერები კედელთან და დახატეთ ბიზნესი მოვლენების ქრონოლოგიად სტიკერებზე. ნარინჯისფერი სტიკერები მოვლენებია; ლურჯი — ბრძანებები, რომლებიც მათ იწვევს; ყვითელი — აგრეგატები, რომლებზეც ისინი ეშვება; ვარდისფერი — გარე სისტემები. ერთ შუადღეში აღმოაჩენთ რეალურ პროცესს, ენას და — რაც მთავარია — სად გადის შემოსაზღვრული კონტექსტების ნაკერები.

ბრძანება → აგრეგატი → მოვლენა, მარცხნიდან მარჯვნივ ქრონოლოგიაზე. ფერები სტიკერის ტიპებს შეესაბამება; ხარვეზები კონტექსტების საზღვრებს ავლენს.

06 · ტაქტიკური პატერნები და ინსტრუმენტები 6 წთ

პატერნები, რომლებიც მოდელს
სუფთად ინარჩუნებენ და კიდეებს გარეთ ტოვებენ.

სტრატეგიული დიზაინი ხაზავს საზღვრებს; ტაქტიკური პატერნები მათ ახორციელებს. სამი მათგანი თითქმის ყოველ DDD პროექტში ამართლებს — ისინი აკავებენ შენახვას, აგრეგატებს შორის ლოგიკასა და უცხო მოდელებს, რომ თქვენს სუფთა დომენში არ შემოიჭრან.

რეპოზიტორია

შეინახეთ მთელი აგრეგატები

კოლექციის მსგავსი ინტერფეისი, რომელიც აგრეგატს ერთ ერთეულად ტვირთავს და ინახავს. დომენი ლაპარაკობს OrderRepo-ზე — არასდროს SQL-ზე ან ORM-ზე.

დომენის სერვისი

ლოგიკა, რომელიც ვერცერთ ენტითში ჯდება

როცა წესი რამდენიმე აგრეგატს მოიცავს და არცერთს ეკუთვნის, მოათავსეთ ის მდგომარეობის გარეშე დომენის სერვისში — საერთო ენით დასახელებულში და არა ნაგვის უჯრა Manager-ში.

დამცავი შრე (ACL)

თარგმნეთ საზღვარზე

საზღვარი, რომელიც უცხო ან ძველ მოდელს თქვენსად აქცევს, რომ მათმა ცნებებმა თქვენი დომენი ვერასდროს დააბინძუროს.

interface OrderRepo {            // a collection-like illusion
  findById(id: OrderId): Order
  save(order: Order): void     // the whole aggregate
}
// domain code depends on OrderRepo — not on SQL.
// SqlOrderRepo / InMemoryOrderRepo implement it,
// so the model stays testable and persistence-agnostic.

დამცავი შრე ძველი CRM-ის ფორმას სუფთა დომენურ ტერმინებად აქცევს — მისი უცნაურობები საზღვარს ვერასდროს კვეთს.

რეპოზიტორია არის დამოკიდებულებების ინვერსია, გამოყენებული მონაცემთა შრეზე; ACL კი Adapter პატერნია, რომელიც მთელ კონტექსტს იცავს. DDD იმავე კლასის დონის ინსტრუმენტებს იყენებს, რომლებიც უკვე იცით — უბრალოდ დომენისკენ მიმართავს მათ.

ინსტრუმენტების პეიზაჟი — სად ჯდება DDD

DDD არის მოდელირების დისციპლინა და არა ბიბლიოთეკა, რომელსაც აიმპორტებთ. ეს არის ადგილები, სადაც ის თქვენს დანარჩენ ინსტრუმენტებს ეხება — აირჩიეთ იმის მიხედვით, რაც მართლა გჭირდებათ, და გახსოვდეთ: პროექტების უმეტესობას მძიმე ინსტრუმენტები საერთოდ არ სჭირდება.

რეალური საქმე საუბარია. ესენი უბრალოდ ვორქშოპს ზედაპირს აძლევს.

Miro / Mural
  • დადებითი — უსასრულო საერთო ტილო დისტანციური event storming-ისთვის; სტიკერები, ხმის მიცემა, შაბლონები.
  • უარყოფითი — ფასიანი ადგილები; ფასილიტაციის გარეშე შეიძლება გაიბეროს.
  • აირჩიეთ განაწილებული გუნდებისთვის, რომლებიც რეგულარულ ვორქშოპებს ატარებენ.
Excalidraw
  • დადებითი — უფასო, მყისიერი, ცერემონიების გარეშე; იდეალურია სწრაფი კონტექსტების რუკისთვის ან პირველი storm-ისთვის.
  • უარყოფითი — ნაკლები ვორქშოპ-ფუნქციონალი (ხმის მიცემა, ტაიმერები, დიდი შაბლონები).
  • აირჩიეთ მსუბუქი ესკიზებისა და დროებითი დიაგრამებისთვის.
ფიზიკური კედელი
  • დადებითი — ყველაზე დიდი გამტარუნარიანობა; ერთ ადგილას მყოფი გუნდები ნამდვილი სტიკერებით ყველაზე სწრაფად მოძრაობენ.
  • უარყოფითი — ჩანაწერი არ რჩება, თუ არ გადაიღეთ; საჭიროა, ყველა ერთ ოთახში იყოს.
  • აირჩიეთ, როცა გუნდი ერთ ადგილასაა — ისევ ოქროს სტანდარტია.

DDD-ის საზღვრები სუფთად ეხმიანება სისტემის დონის ფორმებს — მექანიკა ამ დეკებშია.

კონტექსტი → სერვისი

შემოსაზღვრული კონტექსტი ბუნებრივი ნაკერია, რომლის გასწვრივაც მიკროსერვისი იყოფა — ენა და მფლობელობა ერთად იცვლება.

მოვლენები → ბროკერი

დომენის მოვლენები ხდება ინტეგრაციის მოვლენები, რომლებიც კონტექსტებს შეტყობინებების ბროკერით კვეთს.

ფრეიმვორკები (არჩევითი)

ისეთი ინსტრუმენტები, როგორიცაა Axon (JVM) ან event-store მონაცემთა ბაზა, ეხმარება event sourcing-სა & CQRS-ს — მაგრამ ისინი იმპლემენტაციის არჩევანია და არასდროს წინაპირობა.

  • აირჩიეთ მხოლოდ მაშინ, როცა event sourcing უკვე ამართლებს.
07 · სტრატეგიული დიზაინი და როდის არ ღირს DDD 4 წთ

დახარჯეთ მოდელირების ძალისხმევა იქ,
სადაც ის მართლა ამართლებს.

DDD-ის ყველაზე მაღალი დონის უნარი აგრეგატები არ არის — ეს არის ცოდნა იმისა, სისტემის რომელი ნაწილები იმსახურებს სრულ მკურნალობას და რომელი უნდა დარჩეს მოსაწყენ CRUD ფორმად. ეს გადაწყვეტილება სტრატეგიული დიზაინია და ხანდახან პასუხია: „აქ DDD საერთოდ არ გამოიყენოთ“.

ბირთვის დომენი

თქვენი კონკურენტული უპირატესობა

ის ნაწილი, რომელიც ბიზნესს განსაკუთრებულს ხდის — ფასწარმოქმნის ძრავა, დამთხვევის ალგორითმი. აქ ჩადეთ საუკეთესო ადამიანები და სრული DDD.

დამხმარე

საჭიროა, მაგრამ არა განსაკუთრებული

საჭიროა, რომ ბირთვმა იმუშაოს, მაგრამ არ გამოგარჩევთ. დაამოდელირეთ მსუბუქად — საკმარისი სტრუქტურა, ზედმეტი გაპრიალების გარეშე.

ზოგადი

ყველას მიერ გადაწყვეტილი

ავთენტიფიკაცია, შეტყობინებები, ბილინგის რელსები. იყიდეთ ან აიღეთ მზა გადაწყვეტა — ნუ დაამოდელირებთ ხელით და სიყვარულით იმას, რასაც SaaS უკვე აკეთებს.

როდის არ უნდა გამოიყენოთ DDD. თუ დომენი მარტივია — ფორმა მონაცემთა ბაზაზე, ძირითადად შექმნა / წაკითხვა / განახლება / წაშლა და მცირე რაოდენობის რეალური წესი — DDD წმინდა ზედნადებია. აგრეგატები და კონტექსტები ცერემონიას ამატებს ყოველგვარი სარგებლის გარეშე. გულწრფელი ნაგულისხმევი წესი: DDD-ს მაშინ მიმართეთ, როცა არსებითი სირთულე მაღალია და დომენი ბიზნესის ბირთვია. სხვა შემთხვევაში იმარჯვებს ჩვეულებრივი CRUD აპლიკაცია.
1ჯერ ენა დაამოდელირეთ. საერთო, მკაცრად შეთანხმებული ენა ყველაზე იაფი და ყველაზე დიდი ეფექტის მქონე პრაქტიკაა მთელ DDD-ში.
2ერთი მოდელი ერთ შემოსაზღვრულ კონტექსტზე. მიეცით სიტყვას უფლება, სხვადასხვა კონტექსტში სხვადასხვა რამ ნიშნავდეს; თარგმნეთ საზღვრებზე და ნუ გააერთიანებთ.
3აგრეგატები ინვარიანტებს იცავს. პატარა, წვდომა მხოლოდ ფესვით, თანმიმდევრული იმავე წამში; დანარჩენი ყველაფერი id-ითა და მოვლენებით.
4დაიცავით მოდელი კიდეებზე. რეპოზიტორიები შენახვის დეტალებს მალავს; დამცავი შრეები უცხო მოდელებს გარეთ ტოვებს.
5ძალისხმევა ბირთვზე დახარჯეთ. სრული DDD იმაზე, რაც გამოგარჩევთ; მსუბუქი მოდელირება დამხმარეზე; ზოგადი იყიდეთ — და საერთოდ გამოტოვეთ DDD, როცა დომენი მარტივია.

60-წამიანი სწრაფი შემოწმება

  • ბევრი აწეწილი ბიზნეს-წესი, რომელსაც სრულად არავინ იგებს? → დაიწყეთ საერთო ენით და ერთი event storming-ის სესიით. მარტო ესეც ღირს.
  • ერთი მოდელი, რომელიც სამ დეპარტამენტს ცუდად ემსახურება? → დაყავით შემოსაზღვრულ კონტექსტებად, სანამ სერვისებს დაყოფდეთ.
  • ძირითადად ფორმები მონაცემთა ბაზაზე და მცირე რაოდენობის რეალური წესები? → გამოტოვეთ ტაქტიკური მექანიკა. გამოიყენეთ მარტივი, შრეებად დაყოფილი CRUD აპლიკაცია.
  • პირველივე დღეს გცდუნებთ აგრეგატები და CQRS? → გაუძელით. პატერნები მაშინ აიღეთ, როცა ტკივილი მოვა და არა უფრო ადრე — იგივე YAGNI დისციპლინა, რაც ყველგან.
ცოდნის შემოწმება

დაგამახსოვრდათ?

ხუთი სწრაფი კითხვა ენაზე, კონტექსტებზე, აგრეგატებზე, მოვლენებსა და სტრატეგიულ გადაწყვეტილებაზე — მყისიერი პასუხი, ავტორიზაციის გარეშე.

შეაფასეთ ეს დასტა
იყავით პირველი

ნავიგაცია ← → ღილაკებით ან სქროლით · უკან ბიბლიოთეკაში