Lớp ứng dụng vs lớp miền?


47

Tôi đang đọc Thiết kế hướng tên miền của Evans và tôi đang thảo luận về kiến ​​trúc phân lớp. Tôi chỉ nhận ra rằng các lớp ứng dụng và miền là khác nhau và nên tách biệt. Trong dự án tôi đang thực hiện, chúng là một loại pha trộn và tôi không thể nói sự khác biệt cho đến khi tôi đọc cuốn sách (và tôi không thể nói nó rất rõ ràng với tôi bây giờ), thực sự.

Câu hỏi của tôi, vì cả hai đều liên quan đến logic của ứng dụng và được cho là sạch các khía cạnh kỹ thuật và trình bày, những lợi thế của việc vẽ ranh giới hai là gì?

Câu trả lời:


36

Gần đây tôi đã đọc DDD. Khi tôi đến phần này, tôi đã rất ngạc nhiên khi biết rằng tôi đã phát hiện ra kiến ​​trúc 4 lớp tương tự mà Evans đã làm. Như @lonelyorms đã chỉ ra, lớp miền phải được cách ly hoàn toàn với phần còn lại của hệ thống. Tuy nhiên, một cái gì đó phải dịch các giá trị cụ thể của UI (chuỗi truy vấn, dữ liệu POST, phiên, v.v.) thành các đối tượng miền. Đây là nơi mà lớp ứng dụng phát huy tác dụng. Công việc của bạn là dịch qua lại giữa UI, lớp dữ liệu và miền, ẩn hiệu quả tên miền khỏi phần còn lại của hệ thống.

Tôi thấy rất nhiều ứng dụng ASP.NET MVC hiện nay có hầu hết logic trong bộ điều khiển. Đây là một nỗ lực thất bại để thực hiện kiến ​​trúc 3 lớp cổ điển. Bộ điều khiển rất khó để kiểm tra đơn vị vì chúng có quá nhiều mối quan tâm cụ thể về UI. Trong thực tế, việc viết một bộ điều khiển sao cho nó không liên quan trực tiếp đến các giá trị "Ngữ cảnh http" là một thách thức nghiêm trọng. Tốt nhất, bộ điều khiển chỉ nên thực hiện dịch thuật, phối hợp công việc và nhổ lại phản hồi.

Nó thậm chí có thể có ý nghĩa để thực hiện xác nhận cơ bản trong lớp ứng dụng. Tên miền cho rằng các giá trị đi vào nó có ý nghĩa (đây có phải là ID hợp lệ cho khách hàng này không và chuỗi này có đại diện cho ngày / giờ không). Tuy nhiên, xác nhận liên quan đến logic kinh doanh (tôi có thể đặt vé máy bay trong quá khứ không?) Nên được dành riêng cho lớp miền.

Martin Fowler thực sự bình luận về việc hầu hết các lớp miền phẳng ngày nay như thế nào . Mặc dù hầu hết mọi người thậm chí không biết lớp ứng dụng là gì, anh ta thấy rằng rất nhiều người tạo ra các đối tượng miền khá câm và các lớp ứng dụng phức tạp phối hợp công việc của các đối tượng miền khác nhau. Tôi có tội với điều này bản thân mình. Điều quan trọng không phải là xây dựng một lớp vì một số cuốn sách đã nói với bạn. Ý tưởng là xác định trách nhiệm và phân tách mã của bạn dựa trên những trách nhiệm đó. Trong trường hợp của tôi, loại "lớp ứng dụng" phát triển tự nhiên khi tôi tăng kiểm thử đơn vị.


9
Tôi không nghĩ những gì bạn nêu ở đây là chính xác: "Tuy nhiên, một cái gì đó phải dịch các giá trị cụ thể của UI (chuỗi truy vấn, dữ liệu POST, phiên, v.v.) thành các đối tượng miền. Đây là nơi lớp ứng dụng phát huy tác dụng". Những gì bạn đang đề cập là trong thuật ngữ của DDD, lớp "Trình bày". Tầng ứng dụng được cho là để giải quyết các mối quan tâm về hệ thống ống nước, đồng thời và xuyên suốt, chỉ là một lớp bao bọc nhỏ trên Lớp Miền. Những gì bạn đang mô tả sẽ tương ứng với một lớp (phụ) trong Lớp trình bày.
nuốt chửng elysium

23

Lấy từ các mẫu thiết kế doanh nghiệp của Martin Fowler, các lớp phổ biến nhất là:

  • Bản trình bày - đây là các dạng xem, mẫu bản trình bày tạo giao diện tương tác cho ứng dụng của bạn (Tôi đang sử dụng tương tác trong trường hợp ứng dụng của bạn được các hệ thống khác truy cập thông qua các dịch vụ web hoặc RMI nên có thể không phải là giao diện người dùng). Điều này cũng bao gồm các bộ điều khiển quyết định cách thức thực hiện các hành động và cách thức.

  • Tên miền - đây là nơi quy tắc kinh doanh và logic của bạn cư trú, mô hình miền của bạn được xác định, v.v.

  • Nguồn dữ liệu - đây là lớp ánh xạ dữ liệu (ORM) và nguồn dữ liệu (cơ sở dữ liệu, hệ thống tệp, v.v.)

Làm thế nào để bạn vẽ ranh giới giữa ba lớp:

  • Không đặt logic cụ thể của bản trình bày trong các mô hình hoặc đối tượng miền của bạn

  • Không đặt logic trong các trang và bộ điều khiển của bạn, nghĩa là logic để lưu đối tượng vào cơ sở dữ liệu, tạo kết nối cơ sở dữ liệu, v.v., điều này sẽ khiến lớp trình bày của bạn dễ vỡ và khó kiểm tra

  • Sử dụng ORM cho phép bạn tách rời quyền truy cập và hành động của nguồn dữ liệu khỏi mô hình

  • Thực hiện theo bộ điều khiển mỏng - mô hình mô hình chất béo, bộ điều khiển dành cho việc kiểm soát quá trình thực thi không thực hiện được, nhiều hơn tại http://www.littlehart.net/atthekeyboard/2007/04/27/fat-models- Dany-controlroll /http://weblog.jamisbuck.org/2006/10/18/kgny-controll-fat-model mô hình, chế độ xem và bộ điều khiển,


17

Lớp miền mô hình hóa việc kinh doanh của ứng dụng của bạn. Đây phải là sự giải thích rõ ràng của bạn về các quy tắc của nó, đó là động lực thành phần và chứa trạng thái của nó tại bất kỳ thời điểm nào.

Lớp ứng dụng "lo lắng" xác định các công việc cần thực hiện để hoàn thành một nhiệm vụ ứng dụng nhất định. Chủ yếu, nó chịu trách nhiệm bắt buộc các công việc tên miền cần thiết tương tác với các dịch vụ khác (bên ngoài hoặc không).

dụ: ứng dụng phần mềm tài chính của tôi có thao tác người dùng để thay đổi trạng thái của thực thể mô hình (thực thể như được định nghĩa trong DDD [89]):

  • "Giám đốc hoạt động có thể phê duyệt một đề xuất tài chính".

Nhưng, là một quá trình ứng dụng, bên cạnh tất cả các hậu quả mô hình của hoạt động này, tôi phải gửi một giao tiếp nội bộ cho những người dùng khác của ứng dụng. Loại công việc này được "phối hợp" trong lớp ứng dụng. Tôi sẽ không muốn lớp miền của mình nghĩ về việc chỉ đạo một dịch vụ nhắn tin. (và chắc chắn đây không phải là trách nhiệm của lớp trình bày). Dù bằng cách nào, một điều chắc chắn là: tôi cần một lớp mới vì lớp miền của tôi là tất cả về hoạt động kinh doanh cốt lõi và lớp trình bày của tôi là tất cả về diễn giải các lệnh của người dùng và trình bày kết quả.

Ghi chú:

  • Kinh doanh là một trong những từ thường dẫn đến nhiều cách hiểu về nghĩa của nó nhưng chắc chắn bạn có thể tìm thấy rất nhiều ví dụ và nói về DDD;
  • DDD là viết tắt của cuốn sách Thiết kế hướng tên miền của Eric Evans và số bên trong dấu ngoặc vuông cho số trang.

6

Lớp miền phải được thiết kế như một lớp cô lập, điều đó có nghĩa là các quy tắc và logic nghiệp vụ sẽ không bị ảnh hưởng với bất kỳ mã nào (trong Lớp ứng dụng, Lớp trình bày và Lớp cơ sở hạ tầng).

Tầng ứng dụng được cho là được thiết kế để cung cấp một số chức năng về giao diện hệ thống (ứng dụng) (nghĩ như API hoặc RESTful) có thể làm gì. Ví dụ: người dùng có thể đăng nhập vào một hệ thống và trong hành động ứng dụng này (đăng nhập), mã lớp ứng dụng sẽ là mã máy khách cho Lớp miền (hoặc Lớp cơ sở hạ tầng), trong đó truy xuất đối tượng miền Người dùng và áp dụng các phương thức của đối tượng này để thực hiện Chức năng 'đăng nhập'.

Lớp ứng dụng cũng phải được thiết kế thành một lớp cách ly, điều đó có nghĩa là các hành vi của ứng dụng sẽ không bị ảnh hưởng với bất kỳ mã nào (trong Lớp trình bày, Lớp miền và Lớp cơ sở hạ tầng).


2
Ít nhất là trong tài liệu như Thiết kế hướng tên miền (Evans), phải thừa nhận rằng các lớp có sự phụ thuộc một chiều ... thực tế là, tại một số điểm, mã của bạn phụ thuộc vào một cái gì đó . UI phụ thuộc vào Ứng dụng, nhưng không phải ngược lại. Ứng dụng phụ thuộc vào Tên miền, nhưng không phải ngược lại. Tên miền trên cơ sở hạ tầng, không phải ngược lại.

1
Sự phụ thuộc là về cách lập trình của bạn, lớp cách ly là về cách bạn thiết kế các lớp hệ thống. Sự phụ thuộc một chiều không phá vỡ khái niệm cách ly ở đây, bởi vì khi bạn lập trình, mã lớp trên cùng sẽ phụ thuộc vào giao diện của lớp thấp hơn là các lớp thực hiện.
stevesun21

Điều đó thật tuyệt vời và trên giấy tờ, nhưng trong thực tế, các yêu cầu nghiệp vụ dẫn đến những thay đổi có thể ảnh hưởng đến giao diện của lớp ứng dụng theo cách thay đổi bong bóng qua lớp trình bày và đôi khi xuống lớp lưu trữ. Đó là tất cả những gì tôi đã nhận được tại ...

Thiết kế lớp cách ly không có nghĩa là không có thay đổi nào được cho phép trong tương lai. Ngược lại, nó làm cho các thay đổi dễ dàng hơn nhiều - dễ kiểm tra hơn và dễ ước tính công trình hơn. Có, một yêu cầu kinh doanh mới có nghĩa là bạn có thể cần thay đổi từ trên xuống dưới, đó không phải là cách bạn đã thực hiện chức năng hiện có trước đây? Nếu bạn có thể thiết kế từng lớp dựa trên các nguyên tắc RẮN, thì bạn có thể thấy rằng bạn chỉ có thể sử dụng lại các chức năng hiện có từ lớp dưới cùng.
stevesun21

3

Quan điểm của Mô hình hướng miền là tách mô hình miền thiết yếu ra và tồn tại mà không có bất kỳ sự phụ thuộc nào vào các lớp khác và các mối quan tâm ứng dụng khác.

Điều này cho phép bạn tập trung vào chính tên miền mà không bị phân tâm (chẳng hạn như phối hợp giữa UI và các dịch vụ kiên trì).


Sau đó, nguồn dữ liệu (một ORM) nằm trong miền?
Maykonn

@Maykonn - Có thể là vậy. Tuy nhiên, ORM không phải là nguồn dữ liệu. Nó là một công cụ giữa mã của bạn và nguồn dữ liệu thực tế (cơ sở dữ liệu quan hệ). Cách bạn truy cập dữ liệu không phải là mối quan tâm của tên miền - nhà xây dựng và nhà máy có thể giải quyết vấn đề đó (và ORM nếu bạn có).
Oded

Tôi đồng ý. Và tôi đã sai về nguồn dữ liệu và ORM. Cảm ơn!
Maykonn

3
  • Lớp ứng dụngLớp miền đều thuộc phạm vi triển khai.
  • Lớp ứng dụng hoạt động như API.
  • Lớp miền hoạt động như một triển khai API, nó chứa logic nghiệp vụ nên nó cũng được gọi là Lớp logic nghiệp vụ.

nhập mô tả hình ảnh ở đây


mặc dù theo cách này .... tôi cảm thấy được giác ngộ
Nikos

2

Lý do chính cho những ranh giới này là sự tách biệt các mối quan tâm . Mã truy cập vào kho lưu trữ dữ liệu chỉ cần phải lo lắng về việc truy cập vào kho lưu trữ dữ liệu. Nó không nên chịu trách nhiệm cho việc thực thi các quy tắc trên dữ liệu. Ngoài ra, UI phải chịu trách nhiệm cập nhật các điều khiển trong UI, nhận các giá trị từ đầu vào của người dùng và dịch chúng sang thứ gì đó mà lớp miền có thể sử dụng, và không có gì hơn thế. Nó sẽ gọi các hoạt động được cung cấp bởi lớp miền để thực hiện bất kỳ hành động cần thiết nào (ví dụ: lưu tệp này). Một dịch vụ web được gọi phải chịu trách nhiệm chuyển đổi từ phương tiện truyền tải sang thứ gì đó mà lớp miền có thể sử dụng, sau đó gọi lớp miền (hầu hết các công cụ thực hiện rất nhiều công việc này cho bạn).

Sự tách biệt này, khi được thực hiện đúng cách có thể cho bạn khả năng thay đổi các phần của mã mà không ảnh hưởng đến người khác. Ví dụ, có thể thứ tự sắp xếp của một bộ sưu tập các đối tượng được trả về cần phải thay đổi. Vì bạn biết rằng lớp chịu trách nhiệm thao tác dữ liệu (thường là lớp logic nghiệp vụ) xử lý công cụ này, bạn có thể dễ dàng xác định nơi mã cần được thay đổi. Cũng như không phải sửa đổi cách truy xuất từ ​​kho lưu trữ dữ liệu hoặc bất kỳ ứng dụng nào sử dụng tên miền (giao diện người dùng và dịch vụ web từ ví dụ của tôi ở trên).

Mục tiêu cuối cùng là làm cho mã của bạn dễ bảo trì nhất có thể.

Là một lưu ý phụ, một số thứ không thể được chim bồ câu đưa vào một lớp cụ thể của miền (ví dụ: đăng nhập, xác nhận và ủy quyền). Các mục này thường được gọi là mối quan tâm xuyên suốt, và trong một số trường hợp có thể được coi là một lớp đứng riêng mà tất cả các lớp khác có thể nhìn thấy và sử dụng.

Cá nhân tôi nghĩ rằng cách tiếp cận nhiều lớp đã lỗi thời và cách tiếp cận dịch vụ tốt hơn. Bạn vẫn có một đường thẳng rõ ràng trên cát như ai sẽ làm gì, nhưng nó không buộc bạn phải có thứ bậc. Ví dụ: dịch vụ đặt hàng mua, dịch vụ thanh toán và dịch vụ vận chuyển, từ góc độ ứng dụng, tất cả các dịch vụ này đại diện cho tên miền của bạn và sự trì hoãn trách nhiệm mà tôi đã mô tả ở trên vẫn còn hiệu lực trong bối cảnh này, nó đã bị thay đổi như vậy rằng tên miền của bạn tồn tại ở nhiều nơi, tiếp tục sử dụng khái niệm phân tách mối quan tâm.


Tôi đã tò mò về vị trí của logic ủy quyền và từ những gì tôi đang cố gắng hiểu, nó phù hợp với 'lớp ứng dụng'. Bạn có muốn chia sẻ một số cái nhìn sâu sắc về lý do tại sao có thể không tốt nhất để chứa nó trong lớp logic đó?

1
Đó là loại câu hỏi hoàn hảo cho trang web này. Bạn nên đăng nó, để mọi người có cơ hội trả lời.
Charles Lambert

@tuespetre Bạn có thể cung cấp một liên kết đến bài viết đó?
mưa phùn
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.