Mã định danh và đối tượng miền làm tham số phương thức


10

Có bất kỳ đối số khách quan nào cho hoặc chống lại việc sử dụng các đối tượng so với ID duy nhất làm tham số phương thức / hàm không? (và các thành viên của các đối tượng khác?). Đặc biệt trong bối cảnh các ngôn ngữ được nhập tĩnh (C # / Java / Scala)

Ưu điểm của chính đối tượng:

  • Nhiều cuộc gọi an toàn hơn. Với ID có nguy cơ đặt sai đối số. Điều này có thể được giảm thiểu bằng cách giữ một lớp 'mini' cho mỗi lớp chỉ lưu trữ ID của lớp đó.
  • Nhận một lần từ sự kiên trì, không cần phải nhận lại
  • Với ID, nếu loại id thay đổi, hãy nói int -> dài, sau đó sẽ yêu cầu thay đổi trên bảng với khả năng xảy ra lỗi .. (Courtsey: https://softwareengineering.stackexchange.com/a/284734/145808 )

Ưu điểm của việc sử dụng ID:

  • Hầu hết thời gian không cần đối tượng thực tế, chỉ cần duy nhất sẽ làm, vì vậy có ID giúp tiết kiệm thời gian để có được nó từ sự kiên trì.

Một hỗn hợp của các kỹ thuật này, theo như tôi có thể thấy, sẽ chỉ có nhược điểm của cả hai và ưu điểm của cả hai.

Cho rằng đây là một vấn đề được xác định cụ thể, tôi hy vọng có câu trả lời khách quan và không- "Tôi nghĩ" hoặc "Tôi thích" ... :-).

EDIT: Bối cảnh trên gợi ý của một người bình luận- Hạn chế duy nhất là một ngôn ngữ được gõ tĩnh. Ứng dụng này là một ứng dụng cho mục đích chung, mặc dù rất vui khi nhận được câu trả lời dựa trên các tình huống sử dụng cụ thể.

EDIT: Một số bối cảnh nữa. Nói rằng tôi có một hệ thống quản lý sách. Mô hình của tôi là:

Book: { id: Int, isbn: String, donatedBy: Member, borrowedBy: Member }
Member: {id: Int, name: String}

Table- wishlist: { isbn: String, memberId: Int}
Table- borrows:  { id: Int, memberId: Int}  

Method: 
isInWishList( book: Book, member: Member ) vs isInWishList( bookId: Int,  memberId: Int)

handleBorrowRequest( memberId: Int, book: Book ){ 
   //the login system doesn't actually get the entire member structure, only the member id. I don't need the full member yet. can run a query to verify that the memberId has less than max allowed books for borrowing. 
}

Tại sao tôi chỉ muốn giữ id mà không phải là thành viên đầy đủ? Nói khi tôi nhận được thông tin về cuốn sách, tôi hiếm khi cần biết về người đã tặng hoặc mượn nó. Lấy thông tin đầy đủ của họ để điền vào các trường được quyên tặng và mượnBy là một việc quá mức cần thiết.

Tất nhiên, đây chỉ là điểm của tôi. Tôi chắc chắn rằng tôi đang thiếu những thứ nên muốn biết những điểm có lợi / chống lại.


Bạn có thể chỉnh sửa câu hỏi của bạn với một chút bối cảnh? Không rõ kịch bản là gì. Tôi sẽ đoán rằng bạn đang nói về các đối tượng được quản lý bởi hệ thống ORM (như Hibernate) và bởi "mini-class", bạn có nghĩa là một đối tượng proxy tải lười biếng.
Darien


Thêm nhận xét ở đây (cho đến khi tôi có thể có đủ ngữ cảnh để mở rộng thành câu trả lời đầy đủ tính năng): Trừ khi bạn là các giá trị ID mã hóa cứng trong mã của bạn (không có gì lớn), bạn vẫn sẽ phải tải các giá trị ID của mình từ đâu đó phải không? "Hầu hết thời gian" cũng khá mơ hồ IMHO ...
hjk

@hjk Đã thêm một số bối cảnh, cảm ơn. Bạn có một điểm - bạn vẫn phải tải các giá trị ID từ một nơi nào đó. Tuy nhiên, nó không phải là không 'chạm' DB mà là về việc giảm thiểu việc sử dụng và băng thông cho DB. Tôi có thể nhận được id của tất cả những người muốn mượn một cuốn sách, nhưng thực sự có được thông tin đầy đủ của họ sẽ là không cần thiết.
0fnt

Dường như điều đó phụ thuộc vào một số điều: (1) liệu các trường hợp sử dụng có yêu cầu các thuộc tính thực tế (cột) hay chỉ ID, tùy thuộc vào chính các trường hợp sử dụng đó; (2) cho dù bạn sử dụng một số kỹ thuật lưu vào bộ nhớ cache hoặc nâng cao hiệu suất sẽ giúp truy vấn ID-to-property dễ dàng và liệu các trường hợp sử dụng của bạn có đủ nặng để phá vỡ các sơ đồ bộ đệm không.
rwong

Câu trả lời:


8

Tùy thuộc vào môi trường và bối cảnh vấn đề của bạn, nhu cầu truy cập cơ sở dữ liệu có thể được giảm thiểu và do đó (IMO), đối số chỉ sử dụng id bị mất.

Ví dụ, Doctrine2 ORM của PHP có EntityManager::getReferencemột proxy được tải một cách lười biếng cho một thực thể bằng cách sử dụng id được cung cấp; Tôi không biết có bao nhiêu ORM khác làm điều đó, nhưng nó phù hợp với khái niệm "lớp học nhỏ" mà bạn đề cập. Đối với hầu hết các ý định và mục đích, đây là một thực thể ngậm nước hoàn toàn, vì vậy bạn có thể vượt qua nó và sử dụng nó như bất kỳ mục đích nào khác.

Trường hợp duy nhất không phải là khi nó được cung cấp một id không hợp lệ và trong trường hợp đó bạn vẫn muốn truy cập cơ sở dữ liệu để xác thực; cộng với, để giảm chi phí nhận thực thể, hầu hết các ORM đều có chức năng bộ nhớ đệm (cấp thứ nhất & thứ hai) có sẵn trong một số hình thức.

Khi chúng tôi giảm nhu cầu và chi phí đi đến cơ sở dữ liệu, chúng tôi chủ yếu bỏ qua việc sử dụng thực thể làm tham số:

  1. Loại an toàn.
  2. Ít kiến ​​thức yêu cầu của người gọi. Nhà phát triển sau 6 tháng không thể chuyển nhầm thành id của thực thể sai.
  3. Giảm chi phí tái cấu trúc. Nếu một phương thức được thay đổi để yêu cầu 2 mẩu thông tin từ thực thể, thì sẽ không mất chi phí trong việc thay đổi người gọi để cung cấp cho nó, giả sử người gọi đã bắt đầu thực thể ngậm nước.
  4. Yêu cầu xác nhận ít hơn cho mỗi phương pháp. Nhiều phương thức có thể giả định rằng thực thể mà chúng được cung cấp tồn tại trong cơ sở dữ liệu (vì nó xuất phát từ ORM) và do đó không còn phải xác thực id.
  5. (Có khả năng) ít cuộc gọi cơ sở dữ liệu hơn. Nếu bạn chuyển id cho 3 phương thức và mỗi phương thức phải xác thực nó hoặc tìm nạp thêm dữ liệu trên thực thể, thì số lần gọi cơ sở dữ liệu sẽ gấp 3 lần so với 1 phương thức tìm nạp thực thể và 2 hoạt động trên thực thể đó.

Tất nhiên, có những trường hợp người ta chỉ muốn vượt qua một id: ví dụ: khi vượt qua một ranh giới bối cảnh bị ràng buộc (trong thiết kế điều khiển miền nói). Nếu chúng tôi xem xét hai bối cảnh bị ràng buộc với các khái niệm khác nhau về những gì tạo nên một tài khoản (ví dụ: tài chính và quan hệ khách hàng), thì chúng tôi không thể chuyển tài khoản của bối cảnh A sang ngữ cảnh B. Thay vào đó, id tài khoản (theo ngôn ngữ của tên miền) có thể được thông qua


Bộ nhớ đệm sẽ không mở rộng tốt với nhiều phiên bản ứng dụng đang chạy. Tôi có bộ nhớ đệm của riêng tôi tại chỗ. Các điểm là tuyệt vời mặc dù.
0fnt

Tôi đoán thêm một điểm so với ID là việc sử dụng ID ngụ ý gọi tính bền bỉ bên cạnh xác nhận, vì thực tế cũng nhận được đối tượng.
0fnt

3

Đối với loại câu hỏi này, tôi ủy thác cho bất kỳ giải pháp nào truyền đạt tốt nhất ý định của tôi với tư cách là một lập trình viên, và làm cho công việc của "Tương lai Greg" trở nên dễ dàng nhất.

Sử dụng đối tượng làm đối số giúp dễ dàng thực hiện cuộc gọi phương thức hơn 6 tháng kể từ bây giờ và tôi đã quên các chi tiết nghiệt ngã của ứng dụng này. Để xây dựng dựa trên "cuốn sách này trong ví dụ về danh sách mong muốn của người này", giả sử isInWishListphương pháp thực sự chỉ cần so sánh Id số nguyên của sách và thành viên. Trong thực tế, phương pháp này chỉ cần hai phần dữ liệu để thực hiện công việc. Bây giờ, hãy lùi lại một bước từ phương pháp này và xem xét toàn bộ hệ thống phần mềm. Tôi nghi ngờ nó chỉ yêu cầu Id sách và Id thành viên để hoạt động. Dù sao bạn cũng sẽ lấy toàn bộ cuốn sách và thành viên từ cơ sở dữ liệu trước khi gọi isInWishListnó bởi vì có khả năng bạn sẽ cần phải làm gì đó hơn là chỉ gọi một phương thức này. Có thể bạn làm, nhưng hầu hết các lần bạn sẽ cần phải làm nhiều hơn nữa.

Do đó, thực tế bạn sẽ không phải chịu một hình phạt hiệu suất bằng cách tìm nạp và ánh xạ cả hai đối tượng từ cơ sở dữ liệu. Về mặt lý thuyết bạn sẽ yêu cầu ít cuộc gọi cơ sở dữ liệu hơn, nhưng thực tế bạn sẽ thấy rằng điều này đơn giản là không đúng. Nếu bạn chuyển các Id đó làm tham số trong chuỗi truy vấn trở lại máy chủ, thì vâng, bạn sẽ chỉ cần tìm nạp danh sách mong muốn từ cơ sở dữ liệu. Nhưng đây là một cái nhìn rất hẹp về toàn bộ ứng dụng của bạn. Sẽ có các kịch bản khi bạn đang thực hiện các thao tác khác ngoài việc kiểm tra danh sách mong muốn --- chẳng hạn, thêm một cuốn sách vào danh sách mong muốn. Bạn không muốn thêm các mục trùng lặp.

Tìm giải pháp dễ nhất cho một lập trình viên mới, hoặc Bản thân tương lai của bạn để hiểu, đó là truyền các đối tượng BookMembervào. Chỉ sau khi tìm thấy một vấn đề hiệu suất thực tế, bạn mới thực sự quan tâm đến mình khi chỉ cần truyền Id.

Hoặc, chúng ta có thể nhớ rằng các ngôn ngữ được nhập tĩnh như Java cung cấp quá tải phương thức, do đó bạn có thể có bánh của mình và ăn nó:

public boolean isInWishList(int bookId, int memberId) {
    // ...
}

public boolean isInWishList(Book book, Member member) {
    return isInWishList(book.getId(), member.getId());
}

Câu trả lời thực sự cho câu hỏi này là viết cả hai phương thức, gọi phiên bản chỉ có số nguyên từ phiên bản được gõ mạnh và Bob là chú của bạ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.