11

Nơi tôi làm việc, chúng tôi đã đi qua lại về chủ đề này một số lần và đang tìm kiếm một kiểm tra sanity. Đây là câu hỏi: Các đối tượng nghiệp vụ có phải là các thùng chứa dữ liệu (giống như DTO) hay chúng cũng chứa logic có thể thực hiện một số chức năng trên đối tượng đó.Đối tượng kinh doanh - Thùng chứa hoặc chức năng?

Ví dụ - Lấy đối tượng khách hàng, nó có thể chứa một số thuộc tính chung (Tên, Id, v.v), nên đối tượng khách hàng đó cũng bao gồm các hàm (Lưu, Calc, v.v ...) không?

Một dòng lý luận cho biết tách riêng đối tượng ra khỏi chức năng (chính trách nhiệm duy nhất) và đặt chức năng trong lớp hoặc đối tượng Logic kinh doanh.

Dòng khác của lý luận nói, không, nếu tôi có đối tượng khách hàng, tôi chỉ muốn gọi Customer.Save và được thực hiện với nó. Tại sao tôi cần phải biết làm thế nào để tiết kiệm một khách hàng nếu tôi đang tiêu thụ các đối tượng?

Hai dự án cuối cùng của chúng tôi đã có các đối tượng tách biệt khỏi chức năng, nhưng cuộc tranh luận đã được nâng lên một lần nữa trên một dự án mới. Điều gì có ý nghĩa hơn?

EDIT

Những kết quả rất giống với các cuộc tranh luận của chúng tôi. Một phiếu bầu cho một bên hoặc người khác hoàn toàn thay đổi hướng. Có ai muốn thêm 2 xu của họ không?

EDIT

Cho dù việc lấy mẫu câu trả lời là nhỏ, dường như đa số tin rằng chức năng trong một đối tượng kinh doanh là chấp nhận được miễn là nó là đơn giản nhưng bền bỉ được đặt tốt nhất trong một lớp học/lớp riêng biệt. Chúng tôi sẽ cung cấp cho một thử. Cảm ơn mọi người đã nhập ...

Trả lời

10

Đối tượng là trạng thái và hành vi cùng nhau. Nếu một đối tượng có hành vi hợp lý (ví dụ: tính tuổi cho một Người từ ngày sinh của họ hoặc tổng thuế cho một Hóa đơn), bằng mọi cách, hãy thêm nó vào. Các đối tượng kinh doanh không có gì hơn DTO được gọi là "mô hình miền thiếu máu". Tôi không nghĩ đó là một yêu cầu thiết kế.

Tính bền bỉ là một loại hành vi đặc biệt. Những gì tôi gọi là "hợp lý" là hành vi kinh doanh. Một đối tượng kinh doanh không cần biết rằng nó liên tục. Tôi muốn nói rằng một DAO có thể giữ kiên trì tách biệt với hành vi kinh doanh. Tôi không đặt "lưu" vào thể loại "hợp lý".

+0

Chỉ cần làm rõ ... suy nghĩ của bạn là tính toán và các chức năng đơn giản khác nên nằm trong đối tượng, nhưng sự kiên trì (tức là các giao dịch db) nên cư trú ở nơi khác. Tôi có đúng không? – Walter

+0

Vâng, đó là những gì tôi đang nói. Không phải là cách duy nhất để làm điều đó, tất nhiên. Một số người thích có đối tượng vẫn tồn tại. Tôi thường không. – duffymo

+0

Chúng tôi đã luôn thảo luận Tất cả chức năng trong đối tượng kinh doanh hoặc Không có. Đây là một thỏa hiệp tốt mà chúng tôi chưa bao giờ nghĩ tới. – Walter

2

Tôi nghĩ điều đó có ý nghĩa hơn đối với các đối tượng kinh doanh để biết cách "xử lý" bản thân, sau đó phải đặt gánh nặng đó ở nơi khác trong hệ thống. Trong ví dụ của bạn, nơi hợp lý nhất để đối phó với cách "lưu" dữ liệu khách hàng sẽ, đối với tôi, trong đối tượng Khách hàng.

Điều này có thể do tôi coi cơ sở dữ liệu là "vùng chứa dữ liệu", vì vậy tôi ủng hộ "đối tượng kinh doanh" là cấp cao hơn để bảo vệ vùng chứa dữ liệu khỏi truy cập trực tiếp VÀ thực thi "quy tắc kinh doanh" chuẩn về cách dữ liệu được truy cập/thao tác.

+5

Tôi muốn nói thay vì đối tượng Khách hàng nên biết cách tạo đại diện "dễ hiểu" (ví dụ:các thuộc tính nào cần được lưu và khôi phục sau); các chi tiết của * thực sự * bền bỉ rằng biểu diễn (ví dụ: trong cơ sở dữ liệu) phải được chuyển sang một lớp khác hoàn toàn. –

+0

Vì BO có thể được sử dụng bởi một tá hệ thống với tất cả các ngôn ngữ và kho dữ liệu khác nhau, tôi rất muốn thấy công việc đó. –

9

Đối tượng kinh doanh Có thể có chức năng kinh doanh.

Tính bền bỉ không phải là chức năng kinh doanh, nhưng là triển khai kỹ thuật.

dài truyện ngắn:

  1. Save/Update/Delete/Tìm vv - tránh xa các đối tượng kinh doanh trong một lớp bền bỉ.
  2. CalculateSalary, ApplyDiscount vv là những phương pháp kinh doanh liên quan và có thể là:
    1. phương pháp của doanh nghiệp đối tượng (để BO là khép kín đại diện của tổ chức) hoặc;
    2. các dịch vụ riêng biệt triển khai chức năng cụ thể (do đó BO hoạt động giống DTO hơn).

Đối với các điểm 2.
tôi nên đề cập rằng cách tiếp cận 2.1 có xu hướng làm cho Bos quá cồng kềnh và vi phạm SRP. Trong khi 2.2 giới thiệu thêm bảo trì độ phức tạp.

Tôi thường số dư ở giữa 2.1 và 2.2 để tôi đặt những thứ tầm thường liên quan đến dữ liệu vào Đối tượng kinh doanh và tạo các dịch vụ phức tạp hơn một chút (nếu có nhiều hơn 4 dòng mã) dịch vụ).

Điều này thay đổi mô hình của Đối tượng kinh doanh để có nhiều đối tượng chuyển dữ liệu hơn.

Nhưng tất cả điều này làm cho dự án dễ phát triển, kiểm tra và bảo trì hơn.

+0

Tôi chia nhỏ 2,1 và 2,2 với số lượng nội dung cần thiết. Các hàm cần đối tượng nghiệp vụ hoặc chỉ các đối tượng liên quan của cùng một nhóm chức năng - đi vào đối tượng (CalculateAge on Person). Quy trình sử dụng các đối tượng không liên quan nhiều hơn (CalculateDiscount khi nó đưa vào tài khoản cư trú, giao hàng, vv) là một dịch vụ riêng biệt, nhiều khả năng ngay cả một mô-đun/lắp ráp riêng biệt. Logic rất phức tạp là một lớp riêng biệt, quá (PaymentPlanCalculator trên một tín dụng), nhưng sử dụng C# tiếp xúc như là phương pháp mở rộng (được sử dụng trên lớp, nhưng kỹ thuật không phải trên nó). – TomTom

+0

Cảm ơn bạn đã giúp tôi đọc trên SRP. Điều đó không có xu hướng sưng lên số lượng các lớp học, làm cho biết nơi để làm việc bảo trì khó khăn hơn? Tôi biết, phải là một câu hỏi hoàn toàn mới. –

1

Đối tượng kinh doanh nên tập hợp dữ liệu và hành vi liên quan của pháp nhân kinh doanh được mô hình hóa bởi đối tượng đó. Hãy nghĩ về nó như thế này: một trong những nguyên lý chính của lập trình hướng đối tượng là gói gọn dữ liệu và các hành vi liên quan trên dữ liệu đó.

Tính bền bỉ không phải là hành vi của đối tượng được lập mô hình. Tôi thấy tiến triển phát triển suôn sẻ hơn nếu các đối tượng kinh doanh tồn tại lâu dài. Phát triển mã mới và kiểm tra đơn vị mã mới xảy ra nhanh hơn và mượt mà hơn nếu các đối tượng kinh doanh không được ràng buộc cụ thể với hệ thống ống nước bên dưới. Điều này là bởi vì tôi có thể giả lập những khía cạnh đó và quên đi việc phải đi qua cơ sở dữ liệu, vv Các bài kiểm tra đơn vị của tôi sẽ thực thi nhanh hơn (một cộng lớn nếu bạn có hàng ngàn bài kiểm tra tự động chạy với mỗi bản dựng) và tôi sẽ có ít căng thẳng hơn bởi vì tôi sẽ không thử nghiệm vì vấn đề kết nối cơ sở dữ liệu (tuyệt vời nếu bạn thường làm việc ngoại tuyến hoặc từ xa và không thể luôn truy cập cơ sở dữ liệu của mình và oh, bằng cách này, các khía cạnh đó (kết nối cơ sở dữ liệu, v.v.) được kiểm tra ở nơi khác!).

Dòng khác của lý luận nói, không, nếu tôi có đối tượng khách hàng, tôi chỉ muốn gọi Customer.Save và được thực hiện với nó. Tại sao tôi cần phải biết làm thế nào để tiết kiệm một khách hàng nếu tôi đang tiêu thụ các đối tượng?

Biết rằng Customer có phương thức Save đã biết cách lưu đối tượng khách hàng. Bạn đã không tránh được vấn đề bằng cách nhúng logic đó vào đối tượng kinh doanh của bạn. Thay vào đó, bạn đã tạo cơ sở mã của mình chặt chẽ hơn và do đó khó duy trì và kiểm tra hơn. Đẩy lùi trách nhiệm của việc kiên trì đối tượng cho người khác.

+0

Dường như hầu hết các câu trả lời ở đây đều áp dụng cách tiếp cận rất đơn phương. Chỉ có một ngôn ngữ, và vì vậy bạn có thể conflate một đối tượng 'code' với một đối tượng kinh doanh. Tôi có ngây thơ để có một cái nhìn rộng hơn, rằng phương pháp kinh doanh đối tượng của tôi không được thực hiện trong thiết kế của BO chính nó mà là trong mỗi giải pháp mà tìm cách sử dụng BO đó? –

+0

@Stephanie Page: Nó ít liên quan đến ngôn ngữ và nhiều thứ khác để làm với mô hình tiềm năng. Vấn đề xảy ra khi trọng tâm của hành vi đối tượng chuyển từ miền sang môi trường. Nếu các đối tượng đang được lưu vào cơ sở dữ liệu, chúng ta có cần phải bao gồm logic cơ sở dữ liệu trong mỗi đối tượng miền/doanh nghiệp, tức là chuỗi kết nối và ánh xạ trường/cột hoặc câu lệnh SQL không? Cách tiếp cận này nhanh chóng trở thành không thể quản lý trừ khi logic DB được thừa nhận trong lớp riêng của nó. Rất ít ngôn ngữ có thể xử lý tình huống này và giữ cho nó không phải là một mã nguồn cồng kềnh hoặc thừa. –

+1

Tôi thích điều đó: Crosses from the Domain to the Environment ... đó là một phép ẩn dụ hay. –

3

Câu trả lời là như nhau bất kể nền tảng hoặc ngôn ngữ.Chìa khóa cho câu hỏi này là liệu một đối tượng có thể là tự trị hoặc liệu có tốt hơn cho bất kỳ hành vi nào được đưa ra giữa các đối tượng có trách nhiệm tập trung hơn hay không.

Đối với mỗi lớp, câu trả lời có thể khác. Chúng tôi kết thúc với một phổ mà theo đó chúng tôi có thể đặt các lớp học dựa trên Mật độ Trách nhiệm .

      (Level of responsibility for behavior) 
     Autonomy - - - - - - - - - - - - - - - - - - - Dependence 
     High 
    C  - <<GOD object>>       <<Spaghetti code>> 
    l  - 
    a  - 
    s  -          
    s  -     
     -       
    s  - 
    i  - 
    z  - 
    e  - <<Template>>        <<Framework>> 
     low 

Giả sử bạn cho phép lớp tự thực hiện tất cả các hành vi hoặc nhiều nhất có thể. Bắt đầu từ phía bên trái của biểu đồ này, khi bạn làm cho lớp của bạn tự chủ hơn, kích thước của lớp sẽ tăng lên trừ khi bạn liên tục cấu trúc lại nó để làm cho nó trở nên chung chung hơn. Điều này dẫn đến một mẫu . Nếu không có tái cấu trúc được thực hiện, temdency là cho lớp để trở thành "thần giống như" bởi vì nếu có một số hành vi cần thiết, nó có một phương pháp cho điều đó. Số lượng các trường và phương thức phát triển và nhanh chóng trở thành không thể quản lý và không thể tránh khỏi. Kể từ khi lớp học đã làm rất nhiều, lập trình viên sẽ thay vì thêm vào monstrosity hơn cố gắng để mảnh nó ngoài và cắt nút Gordian.

Phía bên phải của biểu đồ có các lớp phụ thuộc vào các lớp khác ở mức độ lớn. Nếu mức phụ thuộc cao nhưng lớp cá nhân nhỏ, đó là dấu hiệu của khung ; mỗi lớp không làm được nhiều và đòi hỏi nhiều lớp phụ thuộc để thực hiện một số chức năng. Mặt khác, một lớp phụ thuộc rất cao cũng có một số lượng lớn mã là một dấu hiệu cho thấy lớp học đầy đủ là Spaghetti.

Chìa khóa cho câu hỏi này là xác định nơi bạn cảm thấy thoải mái hơn trên biểu đồ. Trong mọi trường hợp, các lớp riêng lẻ sẽ kết thúc trên biểu đồ trừ khi một số nguyên tắc tổ chức được áp dụng, đó là cách bạn có thể đạt được kết quả của Mẫu hoặc Framework.

Chỉ cần viết rằng, tôi sẽ nói rằng có sự tương quan giữa kích thước lớp học và mức độ tổ chức. Robert C. Martin (hoặc "Chú Bob") bao gồm các nền tảng tương tự với các gói phụ thuộc trong bài báo rất kỹ lưỡng của mình trên Design Principles and Design Patterns. JDepend là việc triển khai các ý tưởng đằng sau biểu đồ ở trang 26 và bổ sung static analysis tools chẳng hạn như CheckstylePMD.

+1

+1 Phân tích tốt. Điều này sẽ thêm rất nhiều vào cuộc tranh luận của chúng tôi. Cảm ơn. – Walter

+0

Mất bao lâu để đồ thị hoạt động? Câu trả lời rất hay ... một trong những câu hỏi hay nhất trên trang web. –

+0

@Stephanie: Phải mất rất nhiều thử và sai. Câu trả lời này là một trong những lý do tôi gửi một yêu cầu tính năng trên Meta để hỗ trợ bảng trong Markdown. http://meta.stackexchange.com/questions/16356/why-cant-table-markup-elements-be-used/29368#29368 –

0

Các đối tượng kinh doanh, như chúng được đặt tên, rõ ràng nên coutain logic kinh doanh riêng của họ, năng động của logic kinh doanh giữa các tên miền đang ở trong lớp dịch vụ.

Mặt khác, BO có thể là thành phần và phương pháp chứa vùng chứa dữ liệu (DTO?) Hay không; nghĩa là BO có chức năng thuần túy không? Điều đó có thể tránh được tất cả các chuyển đổi giữa BO và DTO.

-1

Trong kiến ​​trúc MVC,

Chúng ta có thể nói Mô hình đó có chứa các đối tượng kinh doanh hay không.

2

Chúng tôi đã sử dụng khung công tác CSLA của Rocky Lhotka trong nhiều năm và thích cách nó được thiết kế. Trong khuôn khổ đó, tất cả các chức năng được chứa trong các đối tượng. Trong khi tôi có thể thấy giá trị của việc phân tách logic ra, tôi không nghĩ rằng chúng ta sẽ sớm rời bỏ triết lý này.

+0

Điểm tuyệt vời. Tôi đã sử dụng CSLA trên một vài dự án. Nó không bao giờ xảy ra với tôi để bao gồm nó trong các cuộc tranh luận của chúng tôi. – Walter

Các vấn đề liên quan