Model Domain Kaya vs Anemik [ditutup]

98

Saya memutuskan apakah saya harus menggunakan Rich Domain Model daripada Anemic Domain Model, dan mencari contoh yang baik dari keduanya.

Saya telah membangun aplikasi web menggunakan Model Domain Anemik, didukung oleh Layanan -> Repositori -> Sistem lapisan penyimpanan , menggunakan FluentValidation untuk validasi BL, dan meletakkan semua BL saya di lapisan Layanan.

Saya telah membaca buku DDD Eric Evan, dan dia (bersama dengan Fowler dan lainnya) tampaknya berpikir Anemic Domain Model adalah anti-pola.

Jadi saya hanya ingin mendapatkan sedikit wawasan tentang masalah ini.

Juga, saya benar-benar mencari beberapa contoh (dasar) yang baik dari Model Domain Kaya, dan keuntungan dari Model Domain Anemik yang diberikannya.

Sam
sumber
Anda mungkin juga ingin melihat blog
Japheth Ongeri - inkalimeva
14
DDD> ADM , ADM> DDD , DDD> ADM , ADM> DDD , ADM + DDD ... DDD / ADM, atau cara untuk tidak menyetujui desain perangkat lunak !
sp00m
Berikut adalah contoh cara menghindari model domain anemia: medium.com/@wrong.about/…
Vadim Samokhin
11
Lucu bahwa pertanyaan ini bisa dijawab dengan satu tautan ke proyek dunia nyata yang didanai oleh organisasi nyata. Setelah 5 tahun, tidak ada jawaban yang bagus, IMO. Berbicara itu murah. Tunjukkan kodenya.
Mateusz Stefek

Jawaban:

58

Perbedaannya adalah model anemia memisahkan logika dari data. Logikanya sering ditempatkan di kelas yang bernama **Service, **Util, **Manager, **Helperdan sebagainya. Kelas-kelas ini mengimplementasikan logika interpretasi data dan oleh karena itu mengambil model data sebagai argumen. Misalnya

public BigDecimal calculateTotal(Order order){
...
}

sedangkan pendekatan domain kaya membalik ini dengan menempatkan logika interpretasi data ke dalam model domain kaya. Dengan demikian ia menempatkan logika dan data bersama-sama dan model domain kaya akan terlihat seperti ini:

order.getTotal();

Ini berdampak besar pada konsistensi objek. Karena logika interpretasi data membungkus data (data hanya dapat diakses melalui metode objek) metode dapat bereaksi terhadap perubahan status data lain -> Inilah yang kita sebut perilaku.

Dalam model anemia model data tidak dapat menjamin bahwa mereka dalam keadaan hukum sementara dalam model domain kaya mereka bisa. Model domain kaya menerapkan prinsip-prinsip OO seperti enkapsulasi, penyembunyian informasi dan menyatukan data dan logika dan oleh karena itu model anemia adalah pola anti dari perspektif OO.

Untuk wawasan yang lebih dalam, lihat blog saya https://www.link-intersystems.com/blog/2011/10/01/anemic-vs-rich-domain-models/

René Link
sumber
15
Katakanlah menghitung harga total pesanan melibatkan: 1) Menerapkan diskon yang bergantung pada pelanggan yang menjadi anggota salah satu dari banyak kemungkinan program loyalitas. 2) Menerapkan diskon untuk pesanan yang berisi kelompok item tertentu bersama-sama bergantung pada kampanye pemasaran saat ini yang dijalankan oleh toko. 3) Menghitung pajak di mana jumlah pajak tergantung pada setiap item pesanan tertentu. Menurut Anda, di manakah semua logika ini? Bisakah Anda memberikan contoh pseudo-code sederhana. Terima kasih!
Nik
4
@Nik Dalam model kaya, Pesanan akan memiliki referensi ke objek Pelanggan, dan objek Pelanggan akan mengacu pada Program Loyalitas. Dengan demikian, Order akan memiliki akses ke semua informasi yang diperlukannya tanpa memerlukan referensi eksplisit ke hal-hal seperti layanan dan repositori untuk mengambil informasi tersebut. Namun, tampaknya mudah untuk mengalami kasus di mana referensi siklis terjadi. Ie Order referensi Pelanggan, Pelanggan memiliki daftar semua Pesanan. Saya pikir ini mungkin sebagian mengapa orang lebih memilih Anemic sekarang.
hancurkan
3
@crush Pendekatan yang Anda gambarkan bekerja dengan sangat baik. Ada satu tangkapan. Kemungkinan kami menyimpan entitas di DB. Jadi, untuk menghitung total pesanan kita harus mengambil Pesanan, Pelanggan, Program Loyalitas, Kampanye Pemasaran, Tabel Pajak dari DB. Pertimbangkan juga, Pelanggan memiliki kumpulan Pesanan, Program Loyalitas memiliki kumpulan Pelanggan dan lain sebagainya. Jika kami mengambil semua ini secara naif, kami akan memuat seluruh DB dalam RAM. Ini tentu saja tidak layak, jadi kami hanya memuat data yang relevan dari DB ... 1/2
Nik
3
@Nik "Jika kami mengambil semua ini secara asli, kami akan memuat seluruh DB dalam RAM." Itu juga salah satu kelemahan utama model kaya dalam pikiran saya. Model kaya bagus sampai domain Anda tumbuh besar dan kompleks, dan kemudian Anda mulai mencapai batasan infrastruktur. Namun, di situlah lazy-load ORM dapat membantu. Temukan yang bagus, dan Anda dapat mempertahankan model yang kaya sambil tidak memuat seluruh DB ke dalam memori ketika Anda hanya membutuhkan 1/20 darinya. Meskipun demikian, saya cenderung menggunakan Model Anemia dengan CQRS sendiri setelah bertahun-tahun bolak-balik antara anemia dan kaya.
hancurkan
2
Hal lain yang perlu dipertimbangkan adalah di mana logika domain bisnis Anda berada. Semakin banyak pengembang yang menggesernya keluar dari database, dan ke aplikasi tempatnya menurut pendapat saya. Tetapi jika Anda terjebak dalam situasi di mana perusahaan Anda menuntut agar logika bisnis tetap berada di lapisan database (prosedur tersimpan), maka Anda hampir pasti tidak mendapat manfaat dari juga menambahkan logika itu dalam model domain kaya. Bahkan, Anda bisa saja menyiapkan diri Anda sendiri untuk menghadapi konflik di mana prosedur tersimpan memiliki aturan yang berbeda dari lapisan domain aplikasi Anda ...
hancurkan
54

Bozhidar Bozhanov tampaknya mendukung model anemia di postingan blog ini .

Berikut ringkasan yang dia sajikan:

  • objek domain tidak boleh dikelola pegas (IoC), objek domain tersebut tidak boleh memiliki DAO atau apa pun yang terkait dengan infrastruktur yang diinjeksikan di dalamnya

  • objek domain memiliki objek domain tempat mereka bergantung pada set oleh hibernate (atau mekanisme persistensi)

  • objek domain melakukan logika bisnis, seperti ide inti dari DDD, tetapi ini tidak termasuk kueri database atau operasi CRUD - hanya pada keadaan internal objek

  • DTO jarang dibutuhkan - objek domain adalah DTO itu sendiri dalam banyak kasus (yang menyimpan beberapa kode boilerplate)

  • layanan melakukan operasi CRUD, mengirim email, mengoordinasikan objek domain, menghasilkan laporan berdasarkan beberapa objek domain, menjalankan kueri, dll.

  • lapisan layanan (aplikasi) tidak terlalu tipis, tetapi tidak menyertakan aturan bisnis yang intrinsik ke objek domain

  • pembuatan kode harus dihindari. Abstraksi, pola desain dan DI harus digunakan untuk mengatasi kebutuhan pembuatan kode, dan pada akhirnya - untuk menyingkirkan duplikasi kode.

MEMPERBARUI

Saya baru-baru ini membaca artikel ini di mana penulis menganjurkan mengikuti semacam pendekatan hybrid - objek domain dapat menjawab berbagai pertanyaan hanya berdasarkan statusnya (yang dalam kasus model anemia total mungkin akan dilakukan di lapisan layanan)

geoand
sumber
11
Saya tidak dapat mengekstrak dari artikel itu yang tampaknya didebat Bozho untuk mendukung model domain anemia. lapisan layanan (aplikasi) tidak terlalu tipis, tetapi tidak menyertakan aturan bisnis yang intrinsik ke objek domain . Apa yang saya pahami adalah, objek domain harus berisi logika bisnis yang bersifat intrinsik bagi mereka, tetapi tidak boleh berisi logika infrastruktur lainnya . Bagi saya, pendekatan ini sama sekali bukan model domain anemia.
Utku
8
Juga yang satu ini: objek domain melakukan logika bisnis, seperti ide inti dari DDD, tetapi ini tidak termasuk kueri database atau operasi CRUD - hanya pada status internal objek . Pernyataan ini sepertinya tidak mendukung model domain anemia sama sekali. Mereka hanya menyatakan bahwa logika infrastruktur tidak boleh digabungkan ke objek domain. Setidaknya itulah yang saya mengerti.
Utku
@Utku Dalam pandangan saya, tampaknya cukup jelas bahwa Bozho menganjurkan semacam hibrida antara kedua model, hibrida yang menurut saya lebih dekat dengan model anemia daripada model kaya.
geoand
41

Sudut pandang saya adalah ini:

Model domain anemia = tabel database yang dipetakan ke objek (hanya nilai bidang, tidak ada perilaku nyata)

Model domain kaya = kumpulan objek yang mengekspos perilaku

Jika ingin membuat aplikasi CRUD sederhana, mungkin model anemia dengan framework MVC klasik sudah cukup. Tetapi jika Anda ingin menerapkan beberapa jenis logika, model anemia berarti Anda tidak akan melakukan pemrograman berorientasi objek.

* Perhatikan bahwa perilaku objek tidak ada hubungannya dengan ketekunan. Lapisan yang berbeda (Pemetaan Data, Repositori, dll.) Bertanggung jawab untuk mempertahankan objek domain.

George
sumber
5
Maaf atas ketidaktahuan saya, tetapi bagaimana model domain kaya dapat mengikuti prinsip SOLID jika Anda meletakkan semua logika terkait Entitas di kelas. Hal ini melanggar prinsip SOLID, 'S' tepatnya, yang merupakan singkatan dari single responsability, yang mengatakan bahwa kelas seharusnya hanya melakukan satu hal dan melakukannya dengan benar.
redigaffi
6
@redigaffi Itu tergantung pada bagaimana Anda mendefinisikan "satu hal". Pertimbangkan kelas dengan dua sifat dan dua metode: x, y, sumdan difference. Itu empat hal. Atau Anda bisa membantah itu penambahan dan pengurangan (dua hal). Atau Anda bisa membantah bahwa itu matematika (satu hal). Ada banyak posting blog di luar sana tentang bagaimana Anda menemukan keseimbangan dalam menerapkan SRP. Ini salah satunya: hackernoon.com/…
Rainbolt
2
Di DDD, single-resposibility berarti kelas / model dapat mengelola statusnya sendiri tanpa menyebabkan efek samping apa pun ke sistem secara keseluruhan. Definisi lain apa pun hanya menghasilkan perdebatan filosofis yang membosankan dalam pengalaman saya.
ZombieTfk
12

Pertama-tama, saya menyalin jawaban dari artikel ini http://msdn.microsoft.com/en-gb/magazine/dn385704.aspx

Gambar 1 menunjukkan Model Domain Anemik, yang pada dasarnya adalah skema dengan getter dan setter.

Figure 1 Typical Anemic Domain Model Classes Look Like Database Tables

public class Customer : Person
{
  public Customer()
  {
    Orders = new List<Order>();
  }
  public ICollection<Order> Orders { get; set; }
  public string SalesPersonId { get; set; }
  public ShippingAddress ShippingAddress { get; set; }
}
public abstract class Person
{
  public int Id { get; set; }
  public string Title { get; set; }
  public string FirstName { get; set; }
  public string LastName { get; set; }
  public string CompanyName { get; set; }
  public string EmailAddress { get; set; }
  public string Phone { get; set; }
}

Dalam model yang lebih kaya ini, daripada hanya menampilkan properti untuk dibaca dan ditulis, permukaan publik Pelanggan terdiri dari metode eksplisit.

Figure 2 A Customer Type That’s a Rich Domain Model, Not Simply Properties

public class Customer : Contact
{
  public Customer(string firstName, string lastName, string email)
  {
    FullName = new FullName(firstName, lastName);
    EmailAddress = email;
    Status = CustomerStatus.Silver;
  }
  internal Customer()
  {
  }
  public void UseBillingAddressForShippingAddress()
  {
    ShippingAddress = new Address(
      BillingAddress.Street1, BillingAddress.Street2,
      BillingAddress.City, BillingAddress.Region,
      BillingAddress.Country, BillingAddress.PostalCode);
  }
  public void CreateNewShippingAddress(string street1, string street2,
   string city, string region, string country, string postalCode)
  {
    ShippingAddress = new Address(
      street1,street2,
      city,region,
      country,postalCode)
  }
  public void CreateBillingInformation(string street1,string street2,
   string city,string region,string country, string postalCode,
   string creditcardNumber, string bankName)
  {
    BillingAddress = new Address      (street1,street2, city,region,country,postalCode );
    CreditCard = new CustomerCreditCard (bankName, creditcardNumber );
  }
  public void SetCustomerContactDetails
   (string email, string phone, string companyName)
  {
    EmailAddress = email;
    Phone = phone;
    CompanyName = companyName;
  }
  public string SalesPersonId { get; private set; }
  public CustomerStatus Status { get; private set; }
  public Address ShippingAddress { get; private set; }
  public Address BillingAddress { get; private set; }
  public CustomerCreditCard CreditCard { get; private set; }
}
Razan Paul
sumber
2
Ada masalah dengan metode yang membuat objek dan menetapkan properti dengan objek yang baru dibuat. Mereka membuat kode kurang dapat dikembangkan dan fleksibel. 1) Bagaimana jika konsumen kode ingin membuat bukan Address, tetapi ExtendedAddress, diwarisi dari Address, dengan beberapa properti tambahan? 2) Atau ubah CustomerCreditCardparameter konstruktor untuk diambil BankIDalih-alih BankName?
Lightman
Apa yang membuat alamat membutuhkan layanan tambahan daripada apa yang menyusun objek? Anda dibiarkan dengan injeksi metode untuk mendapatkan layanan tersebut. Bagaimana jika banyak layanan?
hancurkan
8

Salah satu keuntungan kelas domain kaya adalah Anda dapat memanggil perilaku mereka (metode) setiap kali Anda memiliki referensi ke objek di lapisan mana pun. Selain itu, Anda cenderung menulis metode kecil dan terdistribusi yang berkolaborasi bersama. Dalam kelas domain anemia, Anda cenderung menulis metode prosedural gemuk (di lapisan layanan) yang biasanya didorong oleh kasus penggunaan. Mereka biasanya kurang dapat dipelihara dibandingkan dengan kelas domain kaya.

Contoh kelas domain dengan perilaku:

class Order {

     String number

     List<OrderItem> items

     ItemList bonus

     Delivery delivery

     void addItem(Item item) { // add bonus if necessary }

     ItemList needToDeliver() { // items + bonus }

     void deliver() {
         delivery = new Delivery()
         delivery.items = needToDeliver()
     }

}

Metode needToDeliver()akan mengembalikan daftar item yang perlu dikirimkan termasuk bonus. Itu bisa dipanggil di dalam kelas, dari kelas lain yang terkait, atau dari lapisan lain. Misalnya, jika Anda lolos Orderke tampilan, maka Anda dapat menggunakan needToDeliver()pilihan Orderuntuk menampilkan daftar item yang akan dikonfirmasi oleh pengguna sebelum mereka mengklik tombol simpan untuk mempertahankan Order.

Menanggapi Komentar

Beginilah cara saya menggunakan kelas domain dari pengontrol:

def save = {
   Order order = new Order()
   order.addItem(new Item())
   order.addItem(new Item())
   repository.create(order)
}

Pembuatan Orderdan LineItemdalam satu transaksi. Jika salah satu dari LineItemtidak dapat dibuat, tidak Orderakan dibuat.

Saya cenderung memiliki metode yang mewakili satu transaksi, seperti:

def deliver = {
   Order order = repository.findOrderByNumber('ORDER-1')
   order.deliver()       
   // save order if necessary
}

Semua yang ada di dalamnya deliver()akan dieksekusi sebagai satu transaksi tunggal. Jika saya perlu menjalankan banyak metode yang tidak terkait dalam satu transaksi, saya akan membuat kelas layanan.

Untuk menghindari pengecualian pemuatan lambat, saya menggunakan JPA 2.1 bernama grafik entitas. Misalnya, dalam pengontrol untuk layar pengiriman, saya dapat membuat metode untuk memuat deliveryatribut dan mengabaikan bonus, seperti repository.findOrderByNumberFetchDelivery(). Di layar bonus, saya memanggil metode lain yang memuat bonusatribut dan mengabaikan delivery, seperti repository.findOrderByNumberFetchBonus(). Ini membutuhkan disiplin karena saya masih tidak bisa menelepon deliver()di dalam layar bonus.

jocki
sumber
1
Bagaimana dengan ruang lingkup transaksi?
kboom
5
Perilaku model domain tidak boleh berisi logika persistensi (termasuk transaksi). Mereka harus dapat diuji (dalam pengujian unit) tanpa terhubung ke database. Cakupan transaksi adalah tanggung jawab lapisan layanan atau lapisan persistensi.
jocki
1
Bagaimana dengan pemuatan lambat?
kboom
Saat Anda membuat instance kelas domain dalam pengujian unit, mereka tidak dalam keadaan terkelola karena merupakan objek biasa. Semua perilaku bisa diuji dengan baik.
jocki
Dan apa yang terjadi jika Anda mengharapkan objek domain dari lapisan layanan? Bukankah kemudian dikelola?
kboom
8

Saat saya biasa menulis aplikasi desktop monolitik, saya membuat model domain yang kaya, dulu senang membuatnya.

Sekarang saya menulis layanan mikro HTTP kecil, kode sesedikit mungkin, termasuk DTO anemia.

Saya pikir DDD dan argumen anemia ini berasal dari era aplikasi desktop atau server monolitik. Saya ingat era itu dan saya setuju bahwa model anemia itu aneh. Saya membuat aplikasi trading FX monolitik yang besar dan tidak ada modelnya, sungguh, itu mengerikan.

Dengan layanan mikro, layanan kecil dengan perilakunya yang kaya, bisa dibilang merupakan model yang dapat disusun dan digabungkan dalam suatu domain. Jadi implementasi layanan mikro itu sendiri mungkin tidak memerlukan DDD lebih lanjut. Aplikasi microservice mungkin domainnya.

Layanan mikro pesanan mungkin memiliki fungsi yang sangat sedikit, diekspresikan sebagai sumber daya yang tenang atau melalui SOAP atau apa pun. Kode layanan mikro pesanan mungkin sangat sederhana.

Layanan tunggal (mikro) yang lebih monolitik yang lebih besar, terutama yang mempertahankan modelnya dalam RAM, dapat memanfaatkan DDD.

Luke Puplett
sumber
Apakah Anda memiliki contoh kode untuk layanan mikro HTTP yang mewakili seni Anda saat ini? Tidak meminta Anda untuk menulis apa pun, cukup bagikan tautan jika Anda memiliki sesuatu yang dapat Anda tunjuk. Terima kasih.
Casey Plummer
3

Saya pikir akar masalahnya ada pada dikotomi yang salah. Bagaimana mungkin mengekstrak 2 model ini: kaya dan "anemia" dan membedakannya satu sama lain? Saya pikir itu hanya mungkin jika Anda memiliki ide yang salah tentang apa itu kelas . Saya tidak yakin, tapi saya rasa saya menemukannya di salah satu video Bozhidar Bozhanov di Youtube. Kelas bukanlah metode data + atas data ini. Pemahaman yang sama sekali tidak valid yang mengarah pada pembagian kelas menjadi dua kategori: hanya data, jadi model anemia dan metode + data - jadi model kaya (untuk lebih tepatnya ada kategori ke-3: hanya metode genap).

Yang benar adalah bahwa kelas adalah konsep dalam beberapa model ontologis, kata, definisi, istilah, ide, itu DENOTAT . Dan pemahaman ini menghilangkan dikotomi palsu: Anda tidak dapat memiliki HANYA model anemia atau HANYA model kaya, karena itu berarti model Anda tidak memadai, tidak relevan dengan kenyataan: beberapa konsep hanya memiliki data, beberapa di antaranya hanya memiliki metode, beberapa dari mereka dicampur. Karena kita mencoba mendeskripsikan, dalam hal ini, beberapa kategori, himpunan objek, relasi, konsep dengan kelas, dan seperti yang kita ketahui, beberapa konsep hanya proses (metode), beberapa di antaranya adalah himpunan atribut saja (data), beberapa di antaranya adalah mereka adalah hubungan dengan atribut (campuran).

Saya pikir aplikasi yang memadai harus mencakup semua jenis kelas dan untuk menghindari pembatasan diri secara fanatik hanya pada satu model. Tidak masalah, bagaimana logika merepresentasikan: dengan kode atau dengan objek data yang dapat diinterpretasikan (seperti Free Monads ), bagaimanapun: kita harus memiliki kelas (konsep, denotat) yang mewakili proses, logika, relasi, atribut, fitur, data, dll. Dan bukan untuk mencoba menghindari beberapa dari mereka atau untuk mereduksi semuanya menjadi satu jenis saja.

Jadi, kita dapat mengekstrak logika ke kelas lain dan meninggalkan data dalam yang asli, tetapi itu tidak masuk akal karena beberapa konsep dapat menyertakan atribut dan relasi / proses / metode dan pemisahannya akan menduplikasi konsep di bawah 2 nama yang dapat direduksi menjadi pola: "OBJECT-Attributes" dan "OBJECT-Logic". Tidak apa-apa dalam bahasa prosedural dan fungsional karena keterbatasannya tetapi itu menahan diri secara berlebihan untuk bahasa yang memungkinkan Anda mendeskripsikan semua jenis konsep.

RandomB
sumber
1

Model domain anemia penting untuk ORM dan transfer mudah melalui jaringan (darah kehidupan dari semua aplikasi komersial) tetapi OO sangat penting untuk enkapsulasi dan menyederhanakan bagian 'transaksional / penanganan' dari kode Anda.

Oleh karena itu yang penting adalah dapat mengidentifikasi dan mengubah dari satu dunia ke dunia lainnya.

Beri nama model Anemic sesuatu seperti AnemicUser, atau UserDAO dll sehingga pengembang tahu ada kelas yang lebih baik untuk digunakan, kemudian memiliki konstruktor yang sesuai untuk kelas Anemic none

User(AnemicUser au)

dan metode adaptor untuk membuat kelas anemia untuk pengangkutan / persistensi

User::ToAnemicUser() 

Bertujuan untuk menggunakan tidak ada Pengguna Anemik di mana-mana di luar transportasi / persistensi

andrew pate
sumber
-1

Berikut adalah contoh yang mungkin membantu:

Anemia

class Box
{
    public int Height { get; set; }
    public int Width { get; set; }
}

Non-anemia

class Box
{
    public int Height { get; private set; }
    public int Width { get; private set; }

    public Box(int height, int width)
    {
        if (height <= 0) {
            throw new ArgumentOutOfRangeException(nameof(height));
        }
        if (width <= 0) {
            throw new ArgumentOutOfRangeException(nameof(width));
        }
        Height = height;
        Width = width;
    }

    public int area()
    {
       return Height * Width;
    }
}
Alireza Rahmani Khalili
sumber
Sepertinya ini dapat diubah menjadi ValueObject vs Entity.
kode5
Hanya salin tempel dari Wikipedia tanpa penjelasan apa pun
wst
siapa yang menulis lebih cepat? @w
Alireza Rahmani Khalili
@AlirezaRahmaniKhalili menurut sejarah Wikipedia, mereka adalah yang pertama ... Kecuali, saya tidak mengerti pertanyaan Anda.
wst
-1

Pendekatan klasik untuk DDD tidak menyatakan untuk menghindari Anemic vs Rich Model di semua biaya. Namun, MDA masih dapat menerapkan semua konsep DDD (konteks terbatas, peta konteks, objek nilai, dll.) Tetapi menggunakan model Anemic vs Rich dalam semua kasus. Ada banyak kasus di mana menggunakan Layanan Domain untuk mengatur Kasus Penggunaan Domain yang kompleks di sekumpulan agregat domain sebagai pendekatan yang jauh lebih baik daripada sekadar agregat yang dipanggil dari lapisan aplikasi. Satu-satunya perbedaan dari pendekatan DDD klasik adalah di mana letak semua validasi dan aturan bisnis? Ada konstruksi baru yang dikenal sebagai validator model. Validator memastikan integritas model input lengkap sebelum kasus penggunaan atau alur kerja domain berlangsung. Akar agregat dan entitas anak mengalami anemia tetapi masing-masing dapat memiliki validator modelnya sendiri yang dipanggil sesuai kebutuhan, dengan validator rootnya. Validator masih mengikuti SRP, mudah dirawat dan dapat diuji unit.

Alasan pergeseran ini adalah kami sekarang bergerak lebih ke API first vs pendekatan UX first ke Microservices. REST telah memainkan peran yang sangat penting dalam hal ini. Pendekatan API tradisional (karena SOAP) awalnya terpaku pada API berbasis perintah vs. verba HTTP (POST, PUT, PATCH, GET dan DELETE). API berbasis perintah cocok dengan pendekatan berorientasi objek Model Kaya dan masih sangat valid. Namun, API berbasis CRUD sederhana, meskipun dapat ditampung dalam Model Kaya, jauh lebih cocok dengan model anemia sederhana, validator, dan Layanan Domain untuk mengatur sisanya.

Saya suka DDD dalam semua yang ditawarkannya, tetapi ada saatnya Anda perlu meregangkannya sedikit agar sesuai dengan pendekatan arsitektur yang terus berubah dan lebih baik.

kode5
sumber