Là thực thể tên miền vi phạm Nguyên tắc trách nhiệm duy nhất?


13

Trách nhiệm duy nhất (lý do để thay đổi) của một thực thể nên được xác định duy nhất chính nó, nói cách khác, trách nhiệm của nó là có thể tìm thấy.

Cuốn sách DDD của Eric Evan, pg. 93:

trách nhiệm cơ bản nhất của các Thực thể là thiết lập tính liên tục để hành vi có thể rõ ràng và có thể dự đoán được. Họ làm điều này tốt nhất nếu họ được giữ lại. Thay vì tập trung vào các thuộc tính hoặc thậm chí là hành vi, hãy loại bỏ định nghĩa của đối tượng Thực thể xuống các đặc điểm nội tại nhất, đặc biệt là các đặc điểm nhận dạng nó hoặc thường được sử dụng để tìm hoặc khớp với nó. Chỉ thêm hành vi cần thiết cho khái niệm và thuộc tính được yêu cầu bởi hành vi đó.

Ngoài ra, hãy tìm cách loại bỏ hành vi và thuộc tính vào các đối tượng khác được liên kết với Thực thể cốt lõi. Các vấn đề nhận dạng. Các thực thể có xu hướng thực hiện trách nhiệm của mình bằng cách phối hợp hoạt động của các đối tượng mà chúng sở hữu.

1.

... loại bỏ định nghĩa của đối tượng ENTITY xuống các đặc điểm nội tại nhất, đặc biệt là các đặc điểm nhận dạng nó hoặc thường được sử dụng để tìm hoặc khớp với nó. Chỉ thêm hành vi cần thiết cho khái niệm ...

Khi một thực thể được gán một ID duy nhất , danh tính của nó được thiết lập và vì vậy tôi cho rằng một thực thể đó không cần bất kỳ hành vi nào để duy trì danh tính của nó hoặc để giúp nhận dạng chính nó . Vì vậy, tôi không hiểu loại hành vi nào được tác giả đề cập đến (bên cạnh findmatch hoạt động ) với " hành vi cần thiết cho khái niệm "?

2.

... loại bỏ định nghĩa của đối tượng ENTITY xuống các đặc điểm nội tại nhất, đặc biệt là các đặc điểm nhận dạng nó hoặc thường được sử dụng để tìm hoặc khớp với nó. ... Ngoài ra, hãy tìm cách loại bỏ hành vi và thuộc tính vào các đối tượng khác được liên kết với ENTITY cốt lõi.

Vì vậy, bất kỳ hành vi nào không giúp xác định thực thể, nhưng chúng tôi vẫn mô tả hành vi đó là một đặc điểm nội tại của thực thể đó (tức là sủa là nội tại đối với chó, bay là nội tại đối với máy bay, đẻ trứng là nội tại đối với chim .. .), nên được đưa vào các đối tượng khác được liên kết với thực thể đó (ví dụ: chúng ta nên đặt hành vi sủa vào một đối tượng liên quan đến thực thể chó)?

3.

Ngoài ra, hãy tìm cách loại bỏ hành vi và thuộc tính vào các đối tượng khác được liên kết với ENTITY cốt lõi.

a) MyEntityủy thác trách nhiệm A_respB_respcho các đối tượng ab, tương ứng.

Mặc dù hầu hết A_respB_respcông việc được thực hiện bởi avà các btrường hợp, khách hàng vẫn được phục vụ A_respB_respthông qua MyEntity, điều đó có nghĩa là từ quan điểm của khách hàng, hai trách nhiệm thuộc về MyEntity. Vì vậy, điều đó không có nghĩa là MyEntitycũng có A_respB_resptrách nhiệm và như vậy là vi phạm SRP ?

b) Ngay cả khi chúng tôi cho rằng A_respB_respkhông thuộc về MyEntity, MyEntityvẫn có trách nhiệm AB_respđiều phối hoạt động của các đối tượng ab. Vì vậy, không MyEntityvi phạm SRP vì tối thiểu nó có hai trách nhiệm - để xác định duy nhất chính nó và cả AB_resp?

class MyEntity
{
    private A a = ...
    private B b = ...


    public A GetA()
    { ... }

    public B GetB()
    { ... }

    /* coordinates operations of objects a and b */
    public int AworkB()
    { ... }
}

/* A encapsulates a single responsibility resp_A*/
/* A is value object */
class A
{ ... }

/* B encapsulates a single responsibility resp_B*/
/* B is value object */
class B
{ ... }

CẬP NHẬT:

1.

Hành vi trong bối cảnh này là đề cập đến hành vi ngữ nghĩa. Ví dụ: Thuộc tính trên một lớp (tức là thuộc tính trên một đối tượng miền) được sử dụng để xác định duy nhất nó có hành vi. Trong khi điều này không được đại diện trong mã trực tiếp. Hành vi dự kiến ​​là sẽ không có bất kỳ giá trị trùng lặp nào cho thuộc tính đó.

Vì vậy, trong mã, chúng ta hầu như không bao giờ cần phải thực hiện một hành vi (tức là một hoạt động) bằng cách nào đó duy trì danh tính thực thể, vì như bạn đã giải thích một hành vi như vậy chỉ tồn tại như một khái niệm trong mô hình miền (dưới dạng thuộc tính ID của một thực thể), nhưng khi chúng tôi dịch thuộc tính ID này thành mã, một phần ngữ nghĩa của nó bị mất (tức là phần ngầm đảm bảo giá trị ID là duy nhất bị mất)?

2.

Furthmore, một tài sản như Age không có bối cảnh bên ngoài một Thực thể Người, và do đó, không có ý nghĩa gì khi di chuyển vào một đối tượng khác ... Tuy nhiên, thông tin đó có thể dễ dàng được lưu trữ ở một vị trí riêng biệt mà định danh duy nhất, do đó tham chiếu khó hiểu cho hành vi. Tuổi có thể là một giá trị tải lười biếng.

a) Nếu thuộc Agetính được tải lười biếng, thì chúng ta có thể gọi nó là một hành vi, mặc dù về mặt ngữ nghĩa Agechỉ là một thuộc tính?

3.

Bạn có thể dễ dàng có các hoạt động cụ thể cho Địa chỉ, chẳng hạn như xác minh rằng đó là một địa chỉ hợp lệ. Bạn có thể không biết rằng tại thời điểm thiết kế, nhưng toàn bộ khái niệm này là chia nhỏ các đối tượng thành các phần nhỏ nhất của chúng

Mặc dù tôi đồng ý rằng chúng ta sẽ mất bối cảnh bằng cách di chuyển Agevào các đối tượng khác nhau, bối cảnh sẽ không bị mất nếu chúng ta chuyển DateOfBirthtài sản sang một đối tượng khác, nhưng chúng ta thường không di chuyển nó.

Lý do chính khiến chúng ta chuyển Addresssang một đối tượng khác, nhưng không phải là DateOfBirthgì? Bởi vì DateOfBirththực chất hơn đối với Personthực thể hoặc bởi vì có ít cơ hội hơn mà ở đâu đó trong tương lai chúng ta có thể cần xác định các hoạt động cụ thể DateOfBirth?

4. Tôi phải nói rằng tôi vẫn không biết liệu MyEntitycũng có A_respB_resptrách nhiệm hay không và tại sao MyEntitycũng AB_respkhông được coi là vi phạm SRP

EULERFX

1)

Các hành vi mà tác giả đang đề cập đến là các hành vi liên quan đến thực thể. Đây là những hành vi sửa đổi trạng thái của thực thể

a) Nếu tôi hiểu bạn một cách chính xác, bạn đang nói rằng thực thể đó chỉ nên chứa những hành vi sửa đổi các thuộc tính của nó (tức là trạng thái của nó )?

b) Và những hành vi không nhất thiết phải sửa đổi trạng thái của thực thể , nhưng vẫn được coi là một đặc tính nội tại của thực thể đó (ví dụ: sủa sẽ là đặc điểm nội tại của một Dogthực thể, ngay cả khi nó không sửa đổi Trạng thái của chó )? Chúng ta nên bao gồm những hành vi này trong một thực thể hay chúng nên được chuyển sang các đối tượng khác?

2)

Theo như hành vi di chuyển đến các đối tượng khác, tác giả đang đề cập đến các đối tượng giá trị cụ thể.

Mặc dù trích dẫn của tôi không bao gồm nó, nhưng tác giả có đề cập trong cùng một đoạn rằng trong một số trường hợp, các hành vi (và thuộc tính ) cũng sẽ được chuyển sang các thực thể khác (mặc dù tôi hiểu lợi ích của việc chuyển hành vi sang VO)

3) Giả sử MyEntity(xem câu hỏi 3. trong bài viết gốc của tôi) không vi phạm SRP, chúng tôi có nói rằng trách nhiệm thuộc về MyEntitynhững điều khác cũng bao gồm:

a. A_resp + B_resp + AB_resp ( AB_resptọa độ đối tượng ab)

hoặc là

b. AB_resp + ủy thác A_respB_respcho các đối tượng ( ab) liên kết với MyEntity?

4) Cuốn sách DDD của Eric Evan, pg. 94:

CustomerID là số nhận dạng duy nhất và duy nhất của ENTITY của khách hàng (hình 5.5), nhưng số điện thoại và địa chỉ thường được sử dụng để tìm hoặc khớp với Khách hàng. Tên không xác định danh tính của một người, nhưng nó thường được sử dụng như một phần của phương tiện xác định nó.

Trong ví dụ này, các thuộc tính điện thoại và địa chỉ được chuyển vào Khách hàng, nhưng trên một dự án thực tế, lựa chọn đó sẽ phụ thuộc vào cách khách hàng của tên miền thường được khớp hoặc phân biệt. Ví dụ: nếu Khách hàng có nhiều số điện thoại liên hệ cho các mục đích khác nhau, thì số điện thoại đó không được liên kết với danh tính và nên ở lại với Liên hệ bán hàng.

a)

CustomerID là số nhận dạng duy nhất và duy nhất của ENTITY của khách hàng (hình 5.5), nhưng số điện thoại và địa chỉ thường được sử dụng để tìm hoặc khớp với Khách hàng. Tên không xác định danh tính của một người, nhưng nó thường được sử dụng như một phần của phương tiện xác định nó.

Trích dẫn rằng chỉ các thuộc tính liên quan đến danh tính nên ở trong một thực thể . Tôi giả sử tác giả có nghĩa là thực thể chỉ nên chứa những thuộc tính thường được sử dụng để tìm hoặc khớp với thực thể này , trong khi TẤT CẢ các thuộc tính khác nên được di chuyển?

b) Nhưng các thuộc tính khác nên được di chuyển như thế nào? Ví dụ: giả định ở đây là thuộc tính địa chỉ không được sử dụng để tìm hoặc khớp Customer và do đó chúng tôi muốn chuyển thuộc tính địa chỉ ra khỏi Customer):

nếu thay vì có Customer.Address(loại string) chúng ta tạo một Customer.Addressthuộc tính loại Address, chúng ta đã di chuyển thuộc tính địa chỉ vào một đối tượng VO có liên quan (thuộc loại Address) hay chúng ta sẽ nói rằng Customervẫn chứa thuộc tính địa chỉ ?

c)

Trong ví dụ này, các thuộc tính điện thoại và địa chỉ được chuyển vào Khách hàng, nhưng trên một dự án thực tế, lựa chọn đó sẽ phụ thuộc vào cách khách hàng của tên miền thường được khớp hoặc phân biệt. Ví dụ: nếu Khách hàng có nhiều số điện thoại liên hệ cho các mục đích khác nhau, thì số điện thoại đó không được liên kết với danh tính và nên ở lại với Liên hệ bán hàng.

Không được tác giả trong sai ở đây, vì nếu chúng ta giả định mỗi trong số rất nhiều số điện thoại liên lạcCustomerchỉ có thuộc về đó đặc biệt Customer, sau đó tôi muốn nói những số điện thoại có liên quan đến danh tính cũng giống như khi Customerchỉ có một số điện thoại ?

5)

Lý do tác giả đề xuất tước thực thể xuống là khi ban đầu tạo ra một thực thể Khách hàng, có xu hướng cư trú với bất kỳ thuộc tính nào mà người ta có thể nghĩ là có liên quan đến khách hàng. Đây là một cách tiếp cận tập trung vào dữ liệu mà bỏ qua các hành vi cuối cùng dẫn đến một mô hình miền thiếu máu.

Tắt chủ đề, nhưng tôi nghĩ rằng mô hình miền thiếu máu kết quả từ chuyển hành vi ra khỏi một thực thể , trong khi ví dụ bạn đang Populating một thực thể với nhiều thuộc tính , điều này sẽ dẫn đến Customerviệc có quá nhiều hành vi (kể từ khi chúng tôi có lẽ cũng bao gồm trong Customercác hành vi đó sửa đổi các thuộc tính bổ sung này ) và do đó vi phạm SRP?

cảm ơn


2
Tôi rất muốn giới thiệu loạt video mã sạch robert martins, Cleancoders.com Ông đi sâu vào chi tiết về cách các nguyên tắc khác nhau có thể gây ra vấn đề HOẶC cân bằng lẫn nhau. mặt khác, tôi nghĩ rằng một phần của công thức cho ví dụ của bạn sẽ xem xét khoảng thời gian mà đối tượng Person có liên quan. nếu trong khoảng thời gian ngắn như Mua hàng, thì địa chỉ thanh toán được sử dụng để mua sẽ là một phần của địa chỉ đó và không thể thay đổi. nếu là tài khoản Thư viện thì địa chỉ sẽ có thể thay đổi.
cartalot

2
Tôi nghĩ rằng câu hỏi này có thể vi phạm SRP ...;)
IntelliData

Câu trả lời:


6

Hành vi trong bối cảnh này là đề cập đến hành vi ngữ nghĩa. Ví dụ: Thuộc tính trên một lớp (tức là thuộc tính trên một đối tượng miền) được sử dụng để xác định duy nhất nó có hành vi. Trong khi điều này không được đại diện trong mã trực tiếp. Hành vi dự kiến là sẽ không có bất kỳ giá trị trùng lặp nào cho thuộc tính đó. Một cái gì đó như Địa chỉ có thể có bản sắc riêng, nhưng không tồn tại bên ngoài bối cảnh của một Thực thể Người vẫn nên được chuyển ra ngoài đối tượng của chính nó. Do đó, thúc đẩy thực thể thành một gốc tổng hợp.

Furthmore, một tài sản như Age không có bối cảnh bên ngoài một Thực thể Người, và như vậy, không có ý nghĩa gì để di chuyển vào một đối tượng khác. Bối cảnh sẽ bị mất, và do đó bạn có thể xác định một cách an toàn rằng đó là một giá trị rất cần thiết cho Thực thể Người. Bạn không thể định vị giá trị khác. Tuy nhiên, thông tin đó có thể dễ dàng được lưu trữ ở một vị trí riêng biệt mà định danh duy nhất, do đó tham chiếu đến hành vi khó hiểu . Tuổi có thể là một giá trị tải lười biếng.

Để trả lời câu hỏi của bạn. Không, nó không vi phạm Nguyên tắc Trách nhiệm duy nhất. Thật khó hiểu khi nói rằng một Người chỉ nên có một người, chứ không phải thứ gì đó như Địa chỉ, phức tạp hơn và liên quan đến một người, nên tồn tại như một thực thể của chính họ.

Bạn có thể dễ dàng có các hoạt động cụ thể cho Địa chỉ, chẳng hạn như xác minh rằng đó là một địa chỉ hợp lệ. Bạn có thể không biết rằng tại thời điểm thiết kế, nhưng toàn bộ khái niệm này là chia các đối tượng thành các phần nhỏ nhất của chúng để những thứ như thế này tương đối đơn giản khi được thực hiện sau khi thực tế.

Cập nhật: 1) Trong hầu hết các trường hợp, việc xác thực danh tính này được thực hiện khi lưu đối tượng ra kho lưu trữ dữ liệu. Điều đó có nghĩa là mã đại diện cho xác thực thực thể tồn tại, nhưng nó tồn tại ở nơi khác. Nó thường tồn tại với mã chịu trách nhiệm cấp giá trị nhận dạng. Đó là lý do tại sao tôi nói rằng tính duy nhất không được thể hiện trực tiếp trong mã cho thực thể.

2) Phát biểu đúng sẽ Agelà một thuộc tính có hành vi. Bạn sẽ cần phải ghi lại thực tế rằng Age lười biếng tải để nhà phát triển tiêu thụ tài sản đó có thể đưa ra quyết định chính xác về cách tiêu thụ tài sản đó

3) DateOfBirththường là một đối tượng khác nhau; Một đối tượng ngày đã có các hoạt động được xác định trước trên nó. Trong một số ngôn ngữ, đối tượng date đã có toàn bộ mô hình miền được định nghĩa trên nó. Ví dụ: trong c # bạn có thể chỉ định múi giờ, nếu ngày là UTC, hãy cộng và trừ ngày để có thời gian. Vì vậy, giả định của bạn về việc di chuyển DateOfBirthsẽ là chính xác.

4) Nếu điều duy nhất MyEntitylàm là ủy thác và phối hợp thì không, nó không vi phạm SRP. Trách nhiệm duy nhất của nó là ủy thác và phối hợp và được gọi là mẫu Mặt tiền


Bạn có thể nhìn vào bản cập nhật tôi đã thực hiện?
EdvRusj

Cập nhật câu trả lời của tôi
Charles Lambert

4

Câu hỏi rất hay. SRP không nên được thực hiện khá đơn giản. Nhận dạng / tra cứu không phải là trách nhiệm của đơn vị liên quan đến SRP. Một số người khác chịu trách nhiệm cung cấp cho nó một ID (cụ thể là cửa hàng) và tìm kiếm nó (cụ thể là Kho lưu trữ ).

Mục đích chính của một thực thể là đại diện cho các khái niệm được mô hình phát hiện ra. Sự khác biệt duy nhất giữa một Thực thể và Đối tượng Giá trị là Thực thể có ý nghĩa vượt ra ngoài các thuộc tính không xác định. Ví dụ: nếu một Người thay đổi Tên của mình, anh ta vẫn là cùng một người, chỉ với một tên khác.


1

Khi một thực thể được gán một ID duy nhất, danh tính của nó được thiết lập và vì vậy tôi cho rằng một thực thể đó không cần bất kỳ hành vi nào để duy trì danh tính của nó hoặc để giúp nhận dạng chính nó. Vì vậy, tôi không hiểu loại hành vi nào được tác giả đề cập đến (bên cạnh các hoạt động tìm và khớp) với "hành vi cần thiết cho khái niệm"?

Nếu danh tính được thiết lập thì có, thực thể không cần xác định gì khác. Các hành vi mà tác giả đang đề cập đến là các hành vi liên quan đến thực thể. Đây là những hành vi sửa đổi trạng thái của thực thể. Ví dụ, một Customerthực thể có thể có một MakePreferredhành vi. Lý do tác giả đề xuất tước thực thể xuống là khi ban đầu tạo ra một Customerthực thể, có xu hướng cư trú với bất kỳ thuộc tính nào mà người ta có thể nghĩ là có liên quan đến khách hàng. Đây là một cách tiếp cận tập trung vào dữ liệu mà bỏ qua các hành vi cuối cùng dẫn đến một mô hình miền thiếu máu.

Theo như hành vi di chuyển đến các đối tượng khác, tác giả đang đề cập đến các đối tượng giá trị cụ thể. Lý do nên chuyển hành vi sang VO là một ý tưởng tốt vì VO thường "nhỏ hơn" so với thực thể, do đó tập trung hơn. Hơn nữa, các khía cạnh như tính bất biến và đóng cửa của các hoạt động đơn giản hóa lý do về mã trong khi cũng làm cho nó RẮN hơn .

Cùng với các VO, một thực thể đóng vai trò là một loại neo phối hợp các VO khác nhau thực hiện hành vi của nó.

Liên quan đến SRP, sự nhầm lẫn của bạn không phải là không có cơ sở. Một vấn đề với việc triển khai OOP khuôn mẫu của các thực thể là sự kết hợp giữa bản sắc và trạng thái. Thật vậy, từ góc độ hành vi, bản sắc không liên quan gì đến hành vi. Nói cách khác, danh tính của một thực thể không yêu cầu đối với bất kỳ hành vi nào của nó. Có những triển khai trong đó loại bỏ sự kết hợp này, chẳng hạn như AggregateSource hoặc một cách tiếp cận chức năng mà tôi mô tả ở đây .

Vấn đề khác là, ở một mức độ nào đó, SRP có thể là một biện pháp định tính. Bất cứ ai cũng có thể đưa ra một định nghĩa về trách nhiệm duy nhất mà một số lớp vi phạm. Người ta có thể nói rằng trách nhiệm của thực thể là thực hiện các hành vi cần thiết của thực thể đó. Theo nghĩa đó, nó có một trách nhiệm duy nhất. Hơn nữa, khi một thực thể ủy thác các hành vi cho các VO cấu thành, nó không vi phạm SRP. SRP không cấm thành phần của loại. Chúng tôi thận trọng giảm thiểu việc ghép nối giữa các đối tượng đến mức tối thiểu, giữ giao diện càng trống càng tốt, v.v.

CẬP NHẬT

a) Nếu tôi hiểu bạn một cách chính xác, bạn đang nói rằng thực thể đó chỉ nên chứa những hành vi sửa đổi các thuộc tính của nó (tức là trạng thái của nó)?

Vâng, mặc dù có những ngoại lệ ...

b) Và những hành vi không nhất thiết phải sửa đổi trạng thái của thực thể, nhưng vẫn được coi là một đặc tính nội tại của thực thể đó (ví dụ: sủa sẽ là đặc điểm nội tại của một thực thể Chó, ngay cả khi nó không sửa đổi trạng thái của Dog)? Chúng ta nên bao gồm những hành vi này trong một thực thể hay chúng nên được chuyển sang các đối tượng khác?

Các thực thể có thể chấp nhận các phương thức xuất xưởng để tạo các thể hiện của các thực thể sẽ là các thực thể con một cách hiệu quả, nhưng trong đó các tham chiếu đối tượng không được sử dụng để truyền tải. Trong trường hợp này, thực thể con cần được duy trì bởi dịch vụ ứng dụng. Dịch vụ ứng dụng sử dụng thực thể mẹ để xây dựng thực thể con.

3) Giả sử MyEntity (xem câu hỏi 3. trong bài viết gốc của tôi) không vi phạm SRP, chúng tôi có nói rằng trách nhiệm của MyEntity nằm trong số những điều khác cũng bao gồm:

Bạn đang nhìn vào trách nhiệm từ quan điểm thực hiện. Thay vào đó, hãy xem xét thực thể như một loại hộp đen có trách nhiệm. Làm thế nào nó xử lý những người không quan tâm đến bạn như một người nhìn từ bên ngoài. Phân vùng trách nhiệm giữa các VO hoặc thậm chí các thực thể khác là mối quan tâm thực hiện.

Trích dẫn rằng chỉ các thuộc tính liên quan đến danh tính nên ở trong một thực thể. Tôi giả sử tác giả có nghĩa là thực thể chỉ nên chứa những thuộc tính thường được sử dụng để tìm hoặc khớp với thực thể này, trong khi TẤT CẢ các thuộc tính khác nên được di chuyển?

Cụ thể hơn, các thuộc tính không cần thiết cho hành vi cũng như tra cứu không nên là một phần của thực thể. Quan tâm làm gì? Ngoài ra, với một cái gì đó giống như mẫu mô hình đọc , các thực thể không cần bất cứ thứ gì ngoài các thuộc tính được yêu cầu cho hành vi.

nếu thay vì có Khách hàng. Địa chỉ (thuộc chuỗi loại), chúng tôi tạo một thuộc tính Khách hàng. Địa chỉ loại Địa chỉ, chúng tôi đã di chuyển thuộc tính địa chỉ vào một đối tượng VO được liên kết (thuộc loại Địa chỉ) hay chúng tôi sẽ nói rằng Khách hàng vẫn chứa địa chỉ thuộc tính?

Có, thực tế, không có sự khác biệt giữa địa chỉ chuỗi hoặc địa chỉ VO.

Không phải là tác giả sai ở đây, vì nếu chúng ta giả sử mỗi trong số nhiều số điện thoại liên hệ mà Khách hàng chỉ thuộc về Khách hàng cụ thể đó, thì tôi sẽ nói những số điện thoại này được liên kết với danh tính giống như khi Khách hàng chỉ có một số điện thoại?

Tôi không hiểu ý của tác giả 100%, nhưng tôi nghĩ rằng anh ta chỉ mô tả cách các yêu cầu tra cứu thực thể có thể thay đổi cách thức thực thể và các VO tương ứng của nó là các cấu trúc.

Không có chủ đề, nhưng tôi nghĩ mô hình miền thiếu máu là kết quả của việc di chuyển hành vi ra khỏi một thực thể, trong khi ví dụ của bạn đang tạo ra một thực thể có nhiều thuộc tính, điều này sẽ dẫn đến việc Khách hàng có quá nhiều hành vi (vì chúng tôi cũng có thể bao gồm trong Khách hàng hành vi sửa đổi các thuộc tính bổ sung này) và do đó vi phạm SRP?

Rất nhiều thuộc tính không ngụ ý rất nhiều hành vi. Trong thực tế, nó thường đề nghị ngược lại. Rất nhiều thuộc tính với getters và setters, nhưng không có hành vi đóng gói.


Tôi đã thực hiện cập nhật
EdvRusj

1

TL; DR: bạn đang nghĩ quá. Tuy nhiên, tôi đã rất vui khi lật đổ nó cùng với bạn. Vì vậy, khóa lên ....

Trách nhiệm duy nhất (lý do để thay đổi) của một thực thể nên được xác định duy nhất chính nó, nói cách khác, trách nhiệm của nó là có thể tìm thấy.

Không, điều đó không đúng. Trách nhiệm duy nhất của một thực thể là liên tục.

Bản sắc là một hệ quả nổi bật của sự liên tục. Mô hình hóa nhận dạng như một ý tưởng riêng biệt là một tối ưu hóa hiệu suất.

Đây là một ví dụ: Một khách hàng quen của nhà hàng đưa xe là người phục vụ. Một giờ sau, một khách hàng quen của nhà hàng yêu cầu xe. Người phục vụ có nên cho nó?

Thật dễ dàng để nói rằng người phục vụ nên cung cấp cho chiếc xe nếu người bảo trợ là "giống nhau". Nhưng điều đó thực sự có ý nghĩa gì? Cách đúng đắn để xác định điều đó là bắt đầu với người bảo trợ "bây giờ" và tìm kiếm ngược qua lịch sử của người bảo trợ đó để xem việc đưa chiếc xe cho người phục vụ có phải là một phần của lịch sử đó không.

Chúng tôi thực sự không thể làm điều đó, tất nhiên. Chúng tôi gặp khó khăn trong việc theo dõi chính xác lịch sử của chính mình, không bao giờ bận tâm đến lịch sử của một thứ không phải với chúng tôi suốt thời gian. Vì vậy, thay vì sử dụng lịch sử của người bảo trợ, chúng tôi thực hiện các bước cắt ngắn. Người bảo trợ có cuống vé có cùng số với thẻ hiện được gắn với các khóa không? Giấy phép lái xe trong ví của người bảo trợ có khớp với tên trên tiêu đề tại DMV không, hình ảnh trên giấy phép lái xe có giống với khuôn mặt của người bảo trợ không. Vân vân.

Tóm lại: thay vì kiểm tra lịch sử của người bảo trợ, chúng tôi kiểm tra trạng thái hiện tại của người bảo trợ, để xem liệu trạng thái hiện tại có phù hợp với lịch sử kéo dài giữa thời gian xe đến và yêu cầu trả lại hay không.

Khi mô hình hóa các thực thể, chúng tôi sử dụng một tối ưu hóa tương tự. Chúng tôi cung cấp cho tất cả các thực thể trách nhiệm chung của

  1. Đảm bảo rằng sự khởi đầu của lịch sử bao gồm việc gán một định danh bất biến cho trạng thái của đối tượng
  2. Đảm bảo rằng trạng thái tiếp theo luôn bao gồm một bản sao trung thực của mã định danh của trạng thái trước đó.

Tôi không mô tả trách nhiệm thứ hai của thực thể ở đây; thực thể vẫn chịu trách nhiệm về tính liên tục - đảm bảo rằng lịch sử là một câu chuyện nhất quán. Các trách nhiệm định danh chỉ là một tập hợp con chung cho tất cả các thực thể.

Chúng tôi chưa có sự thực thi nào về tính độc đáo. Điều đó là không thể trong một thực thể duy nhất, bởi vì tính duy nhất đòi hỏi quyền truy cập vào trạng thái của tất cả các thực thể; trong đó một thực thể duy nhất chỉ có quyền truy cập vào chính nó.

Một lần nữa, kiểm tra tất cả các mã định danh mỗi lần là không thực tế, vì vậy thay vào đó chúng tôi đáp ứng tính duy nhất một cách dễ dàng: Mã tạo ra mã định danh tiếp theo không bao giờ được lặp lại.

Cuối cùng, điều này có nghĩa là chúng ta có thể xác minh tính liên tục bằng cách kiểm tra sự tương đương của hai phần trạng thái khác nhau trong bộ nhớ, tiết kiệm rất nhiều phiền phức khi cố gắng truy vấn các biểu đồ chu kỳ.

Bạn dường như cũng đã nhầm lẫn Nguyên tắc Trách nhiệm Đơn lẻ (đó là một ý tưởng thực sự tốt) với một nguyên tắc trách nhiệm nguyên tử. Phân tách trách nhiệm thành các phần nhỏ hơn, dễ quản lý hơn tương thích với SRP.


-3

Vâng, nó phụ thuộc vào cách bạn muốn nhìn vào nó.

Một cách khác là: "Nguyên tắc trách nhiệm đơn lẻ có vi phạm thực thể tên miền không?"

Cả hai đều là hướng dẫn. Không có "nguyên tắc" ở bất cứ đâu trong thiết kế phần mềm. Tuy nhiên, có những thiết kế tốt và thiết kế xấu. Cả hai khái niệm này có thể được sử dụng theo những cách khác nhau, để đạt được một thiết kế tốt.


Downvotes không giải thích được == fanboys SRP
h bob
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.