Mô hình miền thiếu máu: Ưu / Nhược điểm


Câu trả lời:


39

Ưu điểm:

  • Bạn có thể khẳng định đó là một mô hình miền và khoe khoang với bạn bè nhà phát triển của bạn và đưa nó vào sơ yếu lý lịch của bạn.
  • Thật dễ dàng để tạo tự động từ các bảng cơ sở dữ liệu.
  • Nó ánh xạ đến các Đối tượng truyền dữ liệu tốt một cách đáng ngạc nhiên.

Khuyết điểm:

  • Logic miền của bạn tồn tại ở một nơi khác, có thể là trong một lớp có đầy đủ các phương thức lớp (tĩnh). Hoặc mã GUI của bạn. Hoặc ở nhiều nơi, tất cả đều có logic xung đột.
  • Đó là một mô hình phản đối, vì vậy các nhà phát triển khác sẽ hỏi bạn có hiểu các khái niệm về thiết kế hướng đối tượng hay không.

7
+1 Điểm về việc tạo mã từ các bảng cơ sở dữ liệu là rất quan trọng đối với một số người. Nếu bạn đang ở chế độ phát triển tạo mẫu nhanh, thì việc tạo mã tự động là cực kỳ hữu ích. Chúng tôi không giả vờ đây là thiết kế OO thích hợp, và việc đặt mọi thứ lại với nhau một cách cẩu thả sẽ tạo ra "nợ kỹ thuật". Tuy nhiên, trong nhiều dự án, thời gian đưa ra thị trường là ưu tiên cao hơn.
Bill Karwin

62
Không. Mô hình thiếu máu có phải là mô hình chống lại hay không là một vấn đề quan điểm. Fowler (người mà tôi tôn trọng và thường làm theo) cho biết đúng như vậy. Tôi không đồng ý (không phải lời nói của tôi có bất kỳ trọng lượng nào), và nhiều người trong chiến hào OO cũng không đồng ý. Mô hình OO thuần túy thường không được áp dụng trong mọi trường hợp, điều mà cả ngành công nghiệp đều biết từ kinh nghiệm. Hơn nữa, một mô hình thiếu máu vẫn có thể tuân theo các nguyên tắc lập mô hình OO. Vì vậy, việc nhìn thấy các trường hợp cụ thể trong đó một người áp dụng không đặt ra câu hỏi về hiểu biết của một người về thiết kế OO.
luis.espinal

12
Bất kỳ khuôn mẫu nào có phải là chống khuôn mẫu hay không là một vấn đề cần quan tâm. Mô hình miền mạnh là thiết kế OO tốt và mô hình miền thiếu máu là thiết kế OO xấu. Do đó, trong bối cảnh của OO, đó là một mô hình phản đối. Điều đó không có nghĩa là nó không được sử dụng hoặc không phù hợp trong mọi trường hợp, nhưng từ kinh nghiệm cá nhân, tôi coi nó còn tệ hơn chứng nghiện singleton.
Terry Wilcox

7
Tôi cảm thấy có một xu hướng hướng tới lập trình chức năng và mô hình miền có nhiều tác dụng phụ. Tôi cảm thấy rằng mô hình miền thiếu máu đang quay trở lại vì nó cho phép một kiểu lập trình chức năng hơn, trong đó logic kinh doanh của bạn mong đợi dữ liệu vào và trả về dữ liệu đã xử lý. Lớp dịch vụ của bạn giám sát dòng chảy của tất cả, bằng cách biết dữ liệu nào cần được xử lý bằng phương pháp logic nghiệp vụ nào.
Didier A.

2
@TerryWilcox Chà, tôi không phải là chuyên gia về chức năng, nhưng lập trình chức năng cũng có cấu trúc dữ liệu. Mô hình miền thiếu máu sử dụng đối tượng giống như các vùng chứa dữ liệu, chúng giống với cấu trúc hơn. Quan điểm của tôi là với ADM, bạn có thể tiến tới một cách chức năng hơn, nơi bạn có dữ liệu bất biến được chuyển đổi theo thời gian thành các trạng thái mới hơn và mới hơn. Tôi có thể thấy điều này đang được thực hiện trong Scala chẳng hạn, cố gắng tận dụng một chút OOP và áp dụng một số FP cho nó. Một chút giống như họ giải thích nó ở đây: slideshare.net/debasishg/qconny-12
Didier A.

131

Với "Mô hình miền thiếu máu" là chống lại mô hình, tại sao có rất nhiều hệ thống thực hiện điều này?

Tôi nghĩ có một số lý do

1. Độ phức tạp của hệ thống

Trong một hệ thống đơn giản (hầu như là tất cả các ví dụ và mã mẫu bạn tìm thấy trên internet) nếu tôi muốn triển khai:

Thêm sản phẩm vào đơn đặt hàng

Tôi đặt chức năng này trên Đơn đặt hàng

public void Order.AddOrderLine(Product product)
{
    OrderLines.Add(new OrderLine(product));
}

Đẹp và siêu hướng đối tượng.

Bây giờ, hãy nói rằng tôi cần đảm bảo rằng tôi cần xác thực rằng sản phẩm có tồn tại trong kho và ném ngoại lệ nếu nó không.

Tôi thực sự không thể đặt nó trên Đơn đặt hàng được nữa, vì tôi không muốn đơn đặt hàng của mình phụ thuộc vào Khoảng không quảng cáo, vì vậy bây giờ nó cần phải đi vào dịch vụ

public void OrderService.AddOrderLine(Order order, Product product)
{
    if (!InventoryService.Has(product)
       throw new AddProductException

    order.AddOrderLine(product);
}

Tôi cũng có thể chuyển IInventoryService sang Order.AddOrderLine, đây là một tùy chọn khác, nhưng điều đó vẫn khiến Order phụ thuộc vào InventoryService.

Vẫn có một số chức năng trong Order.AddOrderLine, nhưng thông thường nó bị giới hạn trong phạm vi Đơn hàng, trong khi theo kinh nghiệm của tôi, có nhiều Logic nghiệp vụ hơn ngoài phạm vi Đơn hàng.

Khi hệ thống nhiều hơn thì chỉ là CRUD cơ bản, bạn sẽ kết thúc với hầu hết logic của mình trong OrderService và rất ít trong Order.

2. Quan điểm của nhà phát triển về OOP

Có rất nhiều cuộc thảo luận sôi nổi trên internet về việc logic nào nên áp dụng cho các thực thể.

Cái gì đó như

Đặt hàng. Lưu

Order có nên biết cách tự cứu mình hay không? Giả sử chúng tôi có kho lưu trữ cho điều đó.

Bây giờ Order có thể thêm dòng đặt hàng không? Nếu tôi cố hiểu nó bằng tiếng Anh đơn giản, nó cũng không thực sự có ý nghĩa. Người dùng thêm Sản phẩm vào Đơn đặt hàng, vậy chúng ta có nên thực hiện User.AddOrderLineToOrder () không? Điều đó có vẻ như quá mức cần thiết.

Làm thế nào về OrderService.AddOrderLine (). Bây giờ nó có ý nghĩa!

Sự hiểu biết của tôi về OOP là để đóng gói, bạn đặt các hàm trên các lớp mà hàm sẽ cần truy cập trạng thái bên trong của lớp. Nếu tôi cần truy cập bộ sưu tập Order.OrderLines, tôi đặt Order.AddOrderLine () vào Order. Bằng cách này, trạng thái bên trong của lớp không bị lộ.

3. Hộp chứa IoC

Các hệ thống sử dụng thùng chứa IoC thường thiếu máu hoàn toàn.

Đó là vì bạn có thể kiểm tra các dịch vụ / kho lưu trữ có giao diện, nhưng không thể kiểm tra các đối tượng miền (dễ dàng), trừ khi bạn đặt giao diện trên tất cả chúng.

Vì "IoC" hiện đang được ca ngợi là giải pháp cho tất cả các vấn đề lập trình của bạn, rất nhiều người mù quáng làm theo nó và cách này kết thúc với Mô hình miền thiếu máu.

4. OOP khó, thủ tục dễ

Tôi có một chút nghi ngờ về " Lời nguyền của kiến ​​thức " về vấn đề này, nhưng tôi đã phát hiện ra rằng đối với các nhà phát triển mới hơn có DTO và Dịch vụ dễ dàng hơn nhiều so với Rich Domain.

Có thể là do với Rich Domain, khó biết được lớp nào để đặt logic hơn. Khi nào tạo lớp mới? Những mẫu nào để sử dụng? Vân vân..

Với các dịch vụ không trạng thái, bạn chỉ cần đưa nó vào dịch vụ có tên gần nhất.


Tôi nghĩ nó sẽ phụ thuộc vào mức độ phức tạp của nó. 1. Nếu nó đơn giản như trong 1-2 phụ thuộc - tôi sẽ giữ nó trên lớp Order. 2. Nếu độ phức tạp vừa phải - tôi sẽ tạo lớp OrderLines và sử dụng Order.OrderLines để xử lý giao tiếp Order <-> OrderLines cũng như các phụ thuộc liên quan. 3. Nhưng trong trường hợp phức tạp cao - tôi sẽ sử dụng dịch vụ Ứng dụng OrderService để cho phép hầu hết các phụ thuộc bên ngoài, trong khi vẫn giữ bất kỳ mô-đun Đơn hàng nào có phạm vi logic trong Đơn hàng.
Eric P

13
Tóm tắt tuyệt vời - tất cả những lý do này là lý do tại sao nó không phải là một khuôn mẫu chống đối. Sự sùng kính của người Slav đối với OO là một phản vật chất. Bây giờ, hãy thêm tính năng đồng thời mà không cần phép chiếu và xem cách bạn thắt chặt chính mình trong các nút thắt với kiểu Fowler OO. Nhìn vào các công ty đang thực hiện đồng thời ở quy mô (ví dụ như google) và xem họ đang làm bao nhiêu OO.
DanH

Lời nói thân thiện. Sử dụng Grails, tôi không chắc 3 ° dẫn đến thiếu máu. Đối với 1 °, thực sự, bạn kết thúc logic di chuyển trong lớp dịch vụ trong bất kỳ ứng dụng không tầm thường nào. Nhưng tôi vẫn thấy mình có cách tiếp cận tập trung vào miền bằng Grails. Điều này làm cho nó thực sự không tốt, vì miền của bạn là nơi ưa thích của bạn cho logic nhưng bạn sẽ di chuyển các bit lên một lớp khi cần thiết.
youri

4
Tôi không thấy mối tương quan giữa IoC-Anemic. Nó có vẻ như là một vấn đề hoàn toàn không liên quan. Việc các dịch vụ / kho lưu trữ HOẶC các đối tượng miền triển khai các giao diện không liên quan gì đến việc kiểm tra chúng. Thay vào đó, bạn kiểm tra các dịch vụ / kho lưu trữ / các đối tượng miền và tách chúng khỏi các phần phụ thuộc của chúng mà chính chúng triển khai các giao diện. Và việc bạn làm đúng hay không không có bất kỳ mối tương quan nào với IoC mà tôi có thể thấy.

2
Vấn đề về DDD mà tôi đang đấu tranh với Grok là điểm đầu tiên của bạn: "Khi hệ thống chỉ là CRUD cơ bản, bạn sẽ kết thúc với hầu hết logic của bạn trong OrderService và rất ít trong Order." Điều đó hợp lý với tôi, nhưng không phải mục đích của DDD là được sử dụng cho các hệ thống phức tạp hơn thế?
Dan Ling

20

Sau đó, tôi đã có một suy nghĩ trong đầu từ rất lâu rồi. Tôi tin rằng thuật ngữ "OOP" đã mang một ý nghĩa không thực sự dành cho nó. Đảo chữ có nghĩa là "lập trình hướng đối tượng", như chúng ta đều biết. Trọng tâm tất nhiên là từ "định hướng". Nó không phải là "OMP", nghĩa là "lập trình bắt buộc đối tượng". Cả ADM và RDM đều là ví dụ của OOP. Họ sử dụng đối tượng, thuộc tính, giao diện phương thức, v.v. Tuy nhiên, có sự khác biệt giữa ADM và RDM trong cách chúng tôi chọn để tóm tắt mọi thứ. Họ là hai việc khác nhau. Nói rằng ADM là xấu OOP không phải là một nhận định chính xác. Có lẽ chúng ta cần các thuật ngữ khác nhau cho các mức đóng gói khác nhau. Ngoài ra, tôi không bao giờ thích thuật ngữ chống khuôn mẫu. Nó thường được chỉ định cho một cái gì đó bởi các thành viên của một nhóm đối lập. Cả ADM và RDM đều là những mẫu hợp lệ, đơn giản là chúng có các mục tiêu khác nhau và nhằm giải quyết các nhu cầu kinh doanh khác nhau. Những người trong chúng ta, những người thực hành DDD, ít nhất phải đánh giá cao điều này, và không rơi vào trình độ của những người khác bằng cách đánh bại những người chọn triển khai ADM. Chỉ là suy nghĩ của tôi.


16

"Đó là một mô hình phản đối, vì vậy các nhà phát triển khác sẽ hỏi bạn có hiểu các khái niệm về thiết kế hướng đối tượng hay không."

"Mô hình miền thiếu máu là một mô hình phản đối. Mô hình chống không có ưu điểm."

Liệu mô hình miền thiếu máu có phải là mô hình chống lại hay không là một vấn đề cần quan tâm. Martin Fowler nói rằng đúng như vậy, một số nhà phát triển hiểu rõ về OO nói rằng không phải vậy. Việc nêu quan điểm như sự thật hiếm khi hữu ích.

An, ngay cả khi nó được chấp nhận rộng rãi là một mô hình phản đối, thì rất có thể nó vẫn có một số (mặc dù tương đối ít) ngược lại.


2
... là gì? Tôi không cố lừa bạn hay bất kỳ ai, nhưng tôi thực sự tò mò về những ưu điểm. Những nhược điểm đã được đề cập hàng nghìn lần, nhưng tôi vẫn đang tìm kiếm những ưu điểm kiên cường của ADM (ngoài những cụm từ châm biếm).
struppi

6
... điều này có vẻ giống như ai đó đang cố gắng chơi trò quỷ dữ với ít màn trình diễn cho nó. the chances are it would still have some (though relatively little) upside.Sau đó, xin vui lòng đặt tên một số! Ít nhất một, thay vì giả thuyết!
Xe trượt

2
Sẽ dễ dàng hơn để biết một số logic thuộc về bất kỳ thứ gì không liên quan đến lớp đơn (bất kỳ doanh nghiệp thực tế nào). Như đã nói ở những nơi khác, "mô hình miền phong phú" kết thúc có logic ở nhiều nơi (lớp dịch vụ, nhiều lớp tham gia vào đồ thị đối tượng, ...). Ngoài ra, RDM không cho phép bạn có cái nhìn dễ dàng về logic nghiệp vụ đầy đủ, không giúp bạn dễ dàng tránh các chu trình, v.v. Cấu trúc dữ liệu ngu ngốc không có logic có vị trí của chúng trong ứng dụng OO.
ymajoros

1
Tôi thấy bài viết này đưa ra một lý lẽ tốt để nói rằng ADM không phải là một blog phản vật chất.inf.ed.ac.uk/sapm/2014/02/04/
syclee

1
Phản vật chất luôn tạo ra các vấn đề và chúng tôi đã vận chuyển thành công một số ứng dụng hơi lớn (2 hoặc 3 năm phát triển với 10 nhà phát triển làm việc> 300KLOC) với các giải pháp chất lượng cao bằng cách sử dụng mô hình và không cảm thấy có gì đó không ổn với nó, vì vậy sẽ không tệ như vậy nếu nó cho phép bạn tạo mã tốt trong khi sử dụng nó.
Ignacio Soler Garcia,

13

Đối với tôi, có vẻ như sự phản đối chính của Fowler là ADM không phải là OO, theo nghĩa sau. Nếu một người thiết kế một hệ thống "từ đầu" xung quanh các cấu trúc dữ liệu thụ động được thao tác bởi các đoạn mã khác, thì điều này chắc chắn giống thiết kế thủ tục hơn là thiết kế hướng đối tượng.

Tôi đề nghị rằng có ít nhất hai lực lượng có thể tạo ra kiểu thiết kế này:

  1. Các nhà thiết kế / lập trình vẫn nghĩ rằng cần phải làm việc trong môi trường hướng đối tượng theo thủ tục (hoặc giả định rằng họ có thể ...) để tạo ra một hệ thống mới , và

  2. Các nhà phát triển đang làm việc để đưa một "khuôn mặt" giống dịch vụ vào một hệ thống kế thừa được thiết kế theo kiểu không phải OO (bất kể ngôn ngữ).

Ví dụ: nếu một người đang xây dựng một tập hợp các dịch vụ để hiển thị chức năng của một ứng dụng máy tính lớn COBOL hiện có, thì người ta có thể xác định các dịch vụ và giao diện theo mô hình khái niệm không phản ánh cấu trúc dữ liệu COBOL bên trong. Tuy nhiên, nếu dịch vụ ánh xạ mô hình mới với dữ liệu kế thừa để sử dụng triển khai hiện có nhưng ẩn, thì mô hình mới rất có thể "thiếu máu" theo nghĩa của bài báo của Fowler - ví dụ: một tập hợp các định nghĩa kiểu TransferObject và các mối quan hệ không có hành vi thực tế.

Loại thỏa hiệp này có thể rất phổ biến đối với các ranh giới mà tại đó các hệ thống OO thuần túy về mặt lý tưởng phải tương tác với một môi trường không phải là OO hiện có.


8

Mô hình miền thiếu máu (ADM) có thể là một lựa chọn tốt nếu nhóm của bạn không thể hoặc không muốn xây dựng mô hình miền phong phú (RDM) và duy trì nó theo thời gian. Chiến thắng với RDM đòi hỏi sự chú ý cẩn thận đến các yếu tố trừu tượng nổi trội được sử dụng trong hệ thống. Hãy hình dung rằng, trong bất kỳ nhóm nhà phát triển nào, không quá một nửa và có lẽ chỉ một phần mười thành viên của nhóm là có khả năng với những điều trừu tượng. Trừ khi cán bộ này (có lẽ chỉ một nhà phát triển duy nhất) có thể duy trì ảnh hưởng đối với các hoạt động của cả nhóm, RDM sẽ không chống lại được entropy.

Và RDM entropic gây tổn thương, theo những cách cụ thể. Các nhà phát triển của nó sẽ học được những bài học khắc nghiệt. Lúc đầu, họ sẽ có thể đáp ứng kỳ vọng của các bên liên quan, bởi vì họ sẽ không có lịch sử để tồn tại. Nhưng khi hệ thống của chúng trở nên phức tạp hơn (không phức tạp) thì nó sẽ trở nên giòn; các nhà phát triển sẽ cố gắng sử dụng lại mã nhưng có xu hướng tạo ra các lỗi mới hoặc theo dõi quá trình phát triển (và do đó vượt quá các ước tính của họ).

Ngược lại, các nhà phát triển ADM sẽ đặt kỳ vọng thấp hơn cho chính họ, vì họ sẽ không mong đợi sử dụng lại nhiều mã cho các tính năng mới. Theo thời gian, họ sẽ có một hệ thống có nhiều điểm không nhất quán, nhưng có lẽ nó sẽ không bị phá vỡ một cách khó hiểu. Thời gian tiếp thị của họ sẽ lâu hơn so với một RDM thành công, nhưng các bên liên quan của họ khó có thể nhận thấy khả năng này.


5

"Các nhà phát triển đang làm việc để đưa một" khuôn mặt "giống dịch vụ lên một hệ thống kế thừa được thiết kế theo kiểu không phải OO (bất kể ngôn ngữ)."

Nếu bạn nghĩ về nhiều ứng dụng LOB, các hệ thống kế thừa này thường sẽ không sử dụng cùng một mô hình miền như bạn. Mô hình miền Anemic giải quyết vấn đề này với việc sử dụng logic nghiệp vụ trong các lớp dịch vụ. Bạn có thể đặt tất cả mã giao diện này bên trong mô hình của mình (theo nghĩa OO truyền thống) - nhưng bạn thường sẽ mất tính mô-đun.


1
Chơi lô tô. Đây là nơi mà rất nhiều người dường như bỏ lỡ con thuyền. ADM có mục đích. Việc sử dụng sai cách của chúng là một kiểu chống đối, nhưng bản thân chúng thì không.
luis.espinal

4

Khi tôi lần đầu tiên xem bài báo Mô hình miền thiếu máu, tôi đã nghĩ "thánh thúi, đó là những gì tôi làm. Kinh dị!" Tôi kiên trì và làm theo các tài liệu tham khảo đến cuốn sách của Eric Evan, được coi là một ví dụ điển hình, và tải xuống nguồn. Nó chỉ ra rằng "không sử dụng Mô hình miền Anemic" không có nghĩa là "không sử dụng các lớp dịch vụ, không sử dụng người trung gian, không sử dụng chiến lược" hoặc thậm chí "đặt logic vào lớp đang bị thao túng".

Các ví dụ DDD có các lớp dịch vụ, XyzUpdaters, singletons và IoC.

Tôi vẫn bối rối không biết chính xác Mô hình miền thiếu máu là gì. Tôi mong đợi "Tôi sẽ biết nó khi tôi nhìn thấy nó". Bây giờ tôi hài lòng với một ví dụ tích cực về thiết kế tốt.


1
Sau đó tôi đã mua cuốn sách của Eric Evan và tôi thực sự giới thiệu nó. Nó cung cấp các ví dụ chắc chắn về điều ngược lại của các mô hình miền thiếu máu.
jamie

4

Đã làm việc với một hệ thống 'trưởng thành' với ADM và cảm thấy tôi có thể cung cấp một số, ít nhất, phản hồi giai thoại cho câu hỏi này.

1) Thiếu đóng gói

Trong một hệ thống trực tiếp với một ADM, có thể viết ví dụ: 'obj.x = 100; obj.save ', ngay cả khi điều này vi phạm logic kinh doanh. Điều này dẫn đến một số lỗi sẽ không gặp phải nếu các bất biến được mô hình hóa trên đối tượng. Đó là mức độ nghiêm trọng và phổ biến của những lỗi này mà tôi cảm thấy là tiêu cực nghiêm trọng nhất đối với một ADM.

Tôi cảm thấy điều quan trọng là phải chỉ ra ở đây rằng đây là nơi giải pháp chức năng và các giải pháp thủ tục của một ADM khác nhau đáng kể và bất kỳ điểm tương đồng nào mà những người khác có thể đã rút ra về những điểm tương đồng bề mặt giữa ADM và một giải pháp chức năng là ngẫu nhiên.

2) Mã phình to

Tôi ước tính rằng lượng mã được tạo ra trong một ADM gấp 5-10 lần mà giải pháp OOP / RDM sẽ tạo ra. Điều này có lẽ chiếm 50% là sự lặp lại mã, 30% là mã tấm lò hơi, và 20% là việc giải quyết hoặc giải quyết các vấn đề phát sinh do thiếu RDM.

3) Hiểu biết kém về các vấn đề miền

ADM và sự hiểu biết kém về các vấn đề miền đi đôi với nhau. Các giải pháp ngớ ngẩn nảy sinh, các yêu cầu được xem xét kém do khó hỗ trợ chúng với DM hiện có và ADM trở thành một rào cản đáng kể đối với đổi mới kinh doanh do thời gian phát triển lâu hơn và thiếu tính linh hoạt.

4) Khó bảo trì

Cần phải có một mức độ nghiêm ngặt nhất định để đảm bảo rằng khái niệm miền được thay đổi ở tất cả những nơi mà nó được thể hiện, vì khái niệm đó có thể không chỉ là một bản sao và dán lại việc triển khai. Điều này thường dẫn đến các lỗi giống nhau được điều tra và sửa nhiều lần.

5) Tăng khó khăn khi lên máy bay

Tôi nghĩ một trong những lợi ích của RDM là sự gắn kết của các khái niệm cho phép hiểu miền nhanh hơn. Với một khái niệm ADM có thể bị phân mảnh và thiếu rõ ràng do đó các nhà phát triển mới khó tiếp thu hơn.

Tôi cũng muốn đưa chi phí hỗ trợ vận hành cho một ADM cao hơn cho một RDM nhưng điều này sẽ phụ thuộc vào một số yếu tố.

Như những người khác đã chỉ ra, hãy xem DDD (Greg Evans, Vince Vaughn và Scott Millett) để biết những lợi ích của RDM.


1
Greg Evans có phải là đứa con bí mật của Greg Young và Eric Evans? Tôi cũng không biết rằng Vince Vaughn cũng đang viết sách DDD, nhưng có lẽ Vaughn Vernon cũng đã bắt đầu hành động :)
đan vào

Ôi trời, có vẻ như trí nhớ của tôi khi tôi viết những điều trên đã bị xáo trộn phần nào. Cảm ơn vì đã chỉ ra điều đó :)
Mr Morphe

2

Nó tương tự như với hầu hết các mô hình chống đối: nó cho phép bạn giữ cho nhiều người bận rộn trong một thời gian dài. Vì các nhà quản lý có xu hướng được trả nhiều hơn khi họ quản lý nhiều người hơn, nên có động cơ mạnh mẽ để không cải thiện.


1
Không, kinh nghiệm thực tế đời sống
Stephan Eggermont

7
Trong trường hợp đó, hãy để tôi diễn đạt lại. ^^^ Bằng chứng hoàn toàn mang tính giai thoại được sử dụng để suy ra một mệnh đề có vẻ chung chung.
luis.espinal

Khi chúng ta tìm thấy đủ bằng chứng giai thoại, chúng ta có thể rút ra một mô hình. Và mô hình này đã được biết đến và mô tả đầy đủ trong các tài liệu về quản lý thay đổi.
Stephan Eggermont

4
"Và mô hình này đã được biết đến và mô tả đầy đủ trong các tài liệu về quản lý thay đổi." - Xin vui lòng trích dẫn. Hơn nữa, mối tương quan không bao hàm nguyên nhân . Có nghĩa là, chỉ vì bạn thấy mọi người quay bánh xe của họ trong băng đỏ vì các mô hình chống tại chỗ (đặc biệt là các mô hình phần mềm và mô hình miền thiếu máu cho đến thời điểm này), điều đó không có nghĩa là cái tồn tại sau này để biện minh cho cái trước, đó là những gì bạn vừa thổi. Khẩu hiệu tu từ là những bức tranh biếm họa kém để giải thích những vấn đề phức tạp. Vì vậy, một lần nữa, tương quan không có nghĩa là nhân quả.
luis.espinal

4
Bạn có thể muốn đọc Quản lý phần mềm chất lượng của Gerald M. Weinberg, đặc biệt là Tập 4. Và tôi chỉ khẳng định một nguyên nhân có thể cho sự tồn tại tiếp tục chứ không phải cho sự xuất hiện của nó. Nguyên tắc Peter cung cấp một sự thay thế thích hợp.
Stephan Eggermont

2

Phù hợp với câu trả lời của Eric P cũng như những gì một số người khác ở trên đã viết, có vẻ như nhược điểm chính của ADM là mất OOD, đặc biệt là giữ logic và dữ liệu của khái niệm miền cùng nhau để các chi tiết triển khai bị ẩn trong khi API có thể phong phú.

Eric tiếp tục chỉ ra rằng thường có thông tin bên ngoài một lớp miền cần thiết cho logic hoạt động trên lớp đó, chẳng hạn như kiểm tra khoảng không quảng cáo trước khi thêm một mặt hàng vào đơn đặt hàng. Tuy nhiên, tôi đặt câu hỏi, liệu câu trả lời có phải là lớp Dịch vụ nắm giữ logic bao quát này hay liệu nó được xử lý tốt hơn như một phần của thiết kế đối tượng. Ai đó phải biết về đối tượng Khoảng không quảng cáo, đối tượng Sản phẩm và đối tượng Đơn hàng. Có lẽ nó chỉ đơn giản là một đối tượng OrderSystem, có một thành viên Inventory, một danh sách các Đơn đặt hàng, v.v. Điều này trông sẽ không khác lắm so với một Dịch vụ, nhưng tôi nghĩ rằng nó mạch lạc hơn về mặt khái niệm.

Hoặc nhìn theo cách này: Bạn có thể có Người dùng có số dư tín dụng nội bộ và mỗi khi User.addItemToOrder (mục) đó được gọi, nó sẽ nhận được giá của mặt hàng và kiểm tra tín dụng trước khi thêm nó, v.v. Điều đó có vẻ là một OO hợp lý thiết kế. Tôi không chắc chính xác những gì bị mất khi thay thế nó bằng Service.addItemToUserOrder (người dùng, mục), nhưng tôi cũng không chắc những gì đã đạt được. Tôi đoán rằng tổn thất sẽ là lớp mã bổ sung, cộng với phong cách viết bừa bộn và sự thiếu hiểu biết được thực thi về Mô hình miền cơ bản.


1

Cần lưu ý rằng khi các hệ thống phát triển về độ phức tạp và mức độ chi tiết của các biến thể, thì việc đóng gói và hợp nhất các điểm giao diện được cung cấp bởi một mô hình đối tượng truyền thông điệp được thiết kế tốt giúp cho việc thay đổi và duy trì mã quan trọng mà không cần tái cấu trúc rộng rãi.

Các lớp dịch vụ do ADM tạo ra, mặc dù chắc chắn dễ triển khai hơn (vì chúng đòi hỏi tương đối ít suy nghĩ và có nhiều điểm giao diện phi tập trung) có thể sẽ tạo ra rắc rối khi cần sửa đổi một hệ thống đang hoạt động và phát triển.

Tôi cũng có thể nói thêm rằng không phải tất cả các trường hợp đều yêu cầu mô hình miền (hãy để một mình ADM). Đôi khi tốt hơn là sử dụng một kiểu thủ tục / chức năng hơn của tác vụ là theo hướng dữ liệu và không phụ thuộc vào logic / quy tắc nghiệp vụ trên toàn ứng dụng.

Nếu bạn đang cố gắng quyết định ưu và nhược điểm cho toàn bộ ứng dụng, tôi nghĩ điều quan trọng trước tiên là phải thiết kế từng cái trông như thế nào cho ứng dụng nhất định của bạn TRƯỚC KHI bạn bắt đầu viết một dòng mã. Khi bạn đã CRC hoặc đóng khung ứng dụng của mình theo cả hai kiểu, hãy lùi lại một bước và quyết định kiểu nào hợp lý hơn và phù hợp với ứng dụng hơn.

Cũng nên suy nghĩ trước xem cái nào sẽ dễ bảo trì hơn ...


1

Nó cho khả năng dự đoán tốt hơn. Các nhà quản lý thích điều đó, đặc biệt nếu dự án được trả thời gian & vật liệu. Mỗi thay đổi có nghĩa là rất nhiều công việc, vì vậy công việc khó khăn có thể ẩn sau rất nhiều công việc lặp đi lặp lại. Trong một hệ thống DRY được thiết kế tốt, khả năng dự đoán là rất tệ, vì bạn liên tục làm những điều mới.


1

Sau lần đầu tiên tôi đọc cuốn sách của Eric Evans về thiết kế theo hướng miền, tôi không thực sự hiểu rằng nó không chỉ là một loạt các mô hình chiến thuật để thiết kế các lớp mô hình miền tốt.

Sau khi tìm hiểu thêm về chủ đề cũng như sử dụng các mô hình chiến lược, cuối cùng tôi bắt đầu hiểu rằng ban đầu tất cả chỉ là hiểu sâu về các vấn đề kinh doanh mà bạn đang cố gắng giải quyết.

Và chỉ sau đó, bạn mới có thể quyết định những phần nào của hệ thống sẽ phù hợp để áp dụng các mô hình chiến thuật như tổng hợp, thực thể , kho lưu trữ, v.v. cùng với cái gọi là mô hình miền phong phú (trái ngược với mô hình thiếu máu ). Nhưng để hưởng lợi từ những mẫu này, cần phải có đủ độ phức tạp liên quan đến logic nghiệp vụ cho phần đó của hệ thống.

Vì vậy, khi thực hiện giải pháp cho vấn đề hiện tại, trước tiên cần xác định xem vấn đề cụ thể này có được tiếp cận tốt hơn bằng cách sử dụng phương pháp dựa trên CRUD hay đầu tư vào một mô hình miền phong phú cùng với các mô hình chiến thuật đã đề cập.

Nếu CRUD có ý nghĩa hơn, ví dụ: nếu không có logic nghiệp vụ phức tạp và hầu hết logic liên quan đến việc chuyển đổi, chuyển và liên tục dữ liệu triển khai mô hình miền có thể là một quá trình không cần thiết. Điều này không có nghĩa là sẽ không có nhiều việc phải làm mà chỉ đơn giản là nó không phải là các quy tắc kinh doanh tạo ra nhiều nỗ lực thực hiện nhất. Nhưng trong trường hợp này không có cái gọi là mô hình miền thiếu máu , đơn giản vì không có mô hình miền nào cả . Những gì bạn sẽ thấy là những thứ như DTO (Đối tượng truyền dữ liệu) hoặc DAO(Đối tượng truy cập dữ liệu) và các lớp dịch vụ sẽ hoạt động trên dữ liệu. Và các hoạt động tương ứng ở mức độ cao liên quan đến việc chuyển đổi dữ liệu từ biểu diễn này sang biểu diễn khác và di chuyển dữ liệu xung quanh với rất ít hoặc hầu như không có logic nghiệp vụ nào.

Nếu bạn xác định rằng có nhiều logic kinh doanh phức tạp cũng sẽ thay đổi theo thời gian thì việc đầu tư vào một mô hình miền - theo kinh nghiệm của tôi - là một ý kiến ​​hay. Lý do là việc trình bày quan điểm kinh doanh thông qua mã dễ dàng hơn và dễ hiểu các hoạt động tương ứng phản ánh lĩnh vực kinh doanh và các quy tắc của nó. Điều này không có nghĩa là phải có các lớp mô hình miền trong mọi trường hợp sử dụng. Ví dụ: nếu không có trạng thái nào bị thay đổi và tồn tại thì cũng chỉ có thể có các dịch vụ miền chứa logic miền được triển khai giống các hàm thuần túy hơn.

Nhưng nếu cũng có trạng thái được thay đổi và tồn tại cũng có mục đích và ý nghĩa trong lĩnh vực kinh doanh, trạng thái và hành vi thay đổi trạng thái này nên được gói gọn . Với điều đó, không ai có thể vượt qua các quy tắc kinh doanh dễ dàng và do đó dẫn đến trạng thái không hợp lệ cùng với những thất bại nghiêm trọng. Vì vậy, được gọi là các mô hình miền thiếu máu thường là nguồn gốc của các vấn đề như vậy . Trường hợp này thường xảy ra nếu bạn thấy mã trong đó các thành phần khác nhau hoạt động trên cùng một lớp mô hình miền "thiếu máu" kiểm tra một phần trạng thái của nó và thay đổi một số phần của trạng thái mà không quan tâm hoặc biết về những bất biến tổng thể của thực thể kinh doanh đó. Không nhất thiết phải gọi đây là phản mẫu nhưng cần hiểu rằngbạn mất rất nhiều lợi ích của các mô hình tên miền phong phú trong cách tiếp cận dựa trên DDD cùng với các vấn đề đã đề cập. Khi sử dụng mô hình miền mà hành vi và dữ liệu của nó được đặt trong cùng một lớp, cũng có thể có rất nhiều hoạt động gọi "khách hàng" khác nhau của lớp đó nhưng họ không cần quan tâm rằng các bất biến kinh doanh của thực thể kinh doanh được tuân thủ như lớp mô hình miền sẽ luôn xử lý điều đó và cũng có thể thông báo cho "máy khách" về các hoạt động không hợp lệ hoặc thậm chí ném các ngoại lệ như một mạng lưới an toàn.

Vì vậy, điểm mấu chốt , tôi nghĩ rằng điều quan trọng là không nhầm lẫn cấu trúc dữ liệu như các lớp (chẳng hạn như DTO hoặc DAO) với các lớp mô hình miền thiếu máu . Trong một cách tiếp cận dựa trên CRUD được lựa chọn cẩn thận và có chủ đích, không có lợi ích khi cố gắng sử dụng mô hình miền vì có logic nghiệp vụ quá ít phức tạp.

Bằng mô hình miền thiếu máu, tôi sẽ đề cập đến mã mà từ đó tôi có thể thấy rằng có rất nhiều logic nghiệp vụ phức tạp và các quy tắc nghiệp vụ được trải rộng trên các thành phần khác nhau mà lẽ ra phải gần với dữ liệu mà các logic này đang thay đổi.

Ngoài ra còn có một bài học khác mà tôi đã học được trong quá trình này: nếu bạn cố gắng sử dụng cùng một ngôn ngữ kinh doanh (còn được gọi là Ngôn ngữ phổ biến ) trong mã của bạn mà các chủ chốt đang sử dụng trong cuộc sống hàng ngày của họ, bạn đã giành được rất nhiều lợi thế liên quan đến sự hiểu biết miền doanh nghiệp và cải thiện khả năng đọc mã của bạn sẽ giúp bạn rất nhiều cho dù bạn sử dụng phương pháp dựa trên CRUD hay dựa trên mô hình miền.


0

Để mở rộng câu trả lời của Michael, tôi đã nghĩ rằng (khá) rõ ràng mã đó sẽ đi đến đâu: vào một Người dàn xếp chuyên dụng xử lý tương tác giữa Đơn đặt hàng và Khoảng không quảng cáo.

Từ POV của tôi, điều quan trọng về tên miền là nó PHẢI giữ hành vi thử nghiệm đơn giản các isInThisState()phương pháp, v.v. Theo kinh nghiệm của tôi, chúng cũng nằm rải rác trong các giọt dịch vụ (sic :)) ở hầu hết các công ty và hoặc được sao chép lại liên tục. Tất cả đều phá vỡ các quy tắc liên kết tiêu chuẩn.

Theo quan điểm của tôi, cách tiếp cận nên nhằm mục đích hướng tới một DM chứa càng nhiều nét đẹp của biz càng tốt, đặt phần còn lại vào các khu vực được chỉ định rõ ràng (tức là không nằm trong các dịch vụ)


Vấn đề về Mediator là có rất ít sự khác biệt giữa lập trình đó và lập trình thủ tục; bạn chỉ đang nhóm một số hàm không thuộc về một trong hai đối tượng. Việc bạn nhóm chúng vào một đối tượng khác không tạo ra nhiều khác biệt.
Rob Grant

0

Cá nhân tôi thích ADM hơn. chúng tôi có một tập hợp các đối tượng kinh doanh đại diện cho các phần cụ thể trong miền của chúng tôi. Chúng tôi sử dụng các dịch vụ để lưu các đối tượng này vào db. Các đối tượng nghiệp vụ của chúng ta có các phương thức, tuy nhiên các phương thức này chỉ thao túng trạng thái bên trong của nó.

Lợi ích cho chúng ta trong việc sử dụng ADM qua RDM có thể được nhìn thấy trong cách chúng ta duy trì các đối tượng thành db. Các nhà phát triển làm việc trên hệ thống mã kế thừa của chúng tôi có thể sử dụng các đối tượng nghiệp vụ của chúng tôi (từ hệ thống mới) và tiếp tục sử dụng lớp truy cập dữ liệu hiện tại của họ để duy trì các đối tượng này trong db. Việc sử dụng RDM sẽ buộc các nhà phát triển của hệ thống kế thừa của chúng tôi phải đưa các đối tượng Kho lưu trữ vào mô hình kinh doanh của chúng tôi ... điều này sẽ không phù hợp với lớp truy cập dữ liệu hiện tại của họ.


-15

Một mô hình miền thiếu máu là một mô hình chống lại. Anti-pattern không có ưu.


10
Tôi không đồng ý. Hầu hết các Phản vật chất đều có các trường hợp góc trong đó chúng là một giải pháp tốt hơn các lựa chọn thay thế khác.
Bill Karwin

19
Anti-pattern có ưu điểm. Đó là lý do tại sao mọi người sử dụng chúng, mặc dù chúng thường là những ý tưởng tồi.
Kristopher Johnson

6
Phân biệt rằng một cái gì đó là phản mẫu như một sự thật khi nó chỉ là một ý kiến ​​(ngay cả khi đó là một cái gì đó tầm cỡ của Fowler), đó không phải là một hình thức trả lời hợp lệ.
luis.espinal,

@luis: Chỉ là những gì tôi định viết trước khi thấy bạn bình luận. Thêm vào đó, các công cụ tồn tại để phục vụ một mục đích. Nếu Fowler không muốn gọi nó là OO, điều đó cũng tốt. Nhưng điều đó không tự động chỉ ra một giải pháp / kiến ​​trúc / v.v. không tốt.
JensG
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.