Danh sách tham số của phương thức có nên chứa các đối tượng hoặc định danh đối tượng không?


10

Các đội của chúng tôi đang có cuộc thảo luận sau:

Giả sử chúng ta có hai phương pháp sau:

public Response Withdraw(int clubId, int terminalId,int cardId, string invoice, decimal amount);

public Response Withdraw(Club club, Terminal terminal,Card card, string invoice, decimal amount);

những gì được gửi qua mạng chỉ là id.

một bên nói rằng phương pháp đầu tiên là chính xác, bởi vì chúng tôi chỉ có id của thiết bị đầu cuối và câu lạc bộ, và rõ ràng là chúng tôi không có gì khác, đây là cách tiếp cận của tôi.

phía bên kia nói rằng phương pháp thứ hai là đúng bởi vì nó linh hoạt hơn.

Chúng ta đã quen với ý tưởng tham số đối tượng, phía bên kia cũng nghĩ rằng tham số đối tượng nên có các đối tượng làm thuộc tính.

Đó là cách tiếp cận đúng?

Có lẽ có một cách tiếp cận thứ ba thậm chí tốt hơn?


Cái gì? ...........
James

1
Bối cảnh? Dịch vụ web? WCF?
CodeInChaos

1
@James - xin lỗi tôi đã viết câu hỏi này khá nhanh, bạn có thể cho tôi biết những gì không hiểu để tôi có thể chỉnh sửa nó không?
Mithir

@CodesInChaos các phương thức thực sự là các phương thức BL
Mithir

Câu trả lời:


10

Câu trả lời là phụ thuộc vào bối cảnh.

Nếu khách hàng dự kiến ​​sẽ có sẵn tất cả các đối tượng đó , tôi sẽ sử dụng các tham số đối tượng. Nếu không, mã của họ sẽ trông phức tạp hơn mức cần thiết. (Ví dụ, họ sẽ có các cuộc gọi như club.getId(), ví dụ.)

Nếu máy khách sẽ chỉ có sẵn id một cách dễ dàng, thì có lẽ cách tiếp cận thứ hai sẽ tốt hơn, vì bạn có thể không muốn máy khách phải lắp ráp / tải tất cả các đối tượng đó nếu bạn thực sự chỉ cần id.

Một tùy chọn là cung cấp cả hai phương thức , vì vậy khách hàng có thể chọn sử dụng phương thức nào (với điều kiện là điều này không làm lộn xộn API của bạn)

Nói chung, các tham số đối tượng có thể mở rộng hơn, vì nếu trong tương lai bạn cần một phần dữ liệu khác để thực hiện công việc, bạn không cần phải giới thiệu một phương thức khác có thêm thông tin đó.

Cuối cùng, chữ ký phương thức của bạn không nên được quyết định bởi các chi tiết cụ thể về phương thức thực hiện (trong trường hợp của bạn, chính xác những gì đi qua dây). API nên có ý nghĩa trừu tượng để nếu việc triển khai thay đổi, bạn không bị sai lầm.


3
+1 Tôi chỉ thêm một điểm nữa: đối với các phương thức được gọi từ xa ("qua dây"?), Việc truyền các đối tượng có thể đòi hỏi nối tiếp sâu một cây đối tượng mở rộng. ID là sự thay thế tuyệt vời cho các đối tượng khi bạn quan tâm đến kích thước của tải trọng cuộc gọi từ xa.
Ross Patterson

1
Trong trường hợp này, có vẻ như bạn được ghép nối với một tập hợp trừu tượng nên việc chuyển Id sẽ không giúp bạn linh hoạt hơn và có thể sẽ tăng khả năng bạn sẽ đảo ngược các tham số. Câu hỏi đặt ra là làm thế nào chặt chẽ mã trong phương thức được kết hợp với các tóm tắt mà tôi truyền vào? Ví dụ: một phương thức như "validateCreditCard (thẻ chuỗi, chuỗi cvi)" có lẽ nên ở lại với các nguyên thủy để tránh bị ghép chặt với một số loại đối tượng CreditCard.
ipaul

Tôi sẽ gặp ở giữa và sử dụng một giao diện trong danh sách tham số. Sau đó, câu lạc bộ của bạn có thể là một câu lạc bộ, nhưng cũng là một phòng tắm hơi trong tương lai.
Pieter B

13

Cách tiếp cận đầu tiên là biểu thị của Nỗi ám ảnh nguyên thủy . Bởi vì bạn đang truyền ints và chuỗi xung quanh, nên lập trình viên rất dễ mắc lỗi (ví dụ: truyền clubId cho tham số terminalId). Điều này sẽ dẫn đến khó tìm lỗi.

Trong ví dụ thứ hai, không thể vượt qua một câu lạc bộ khi thiết bị đầu cuối được mong đợi - điều này sẽ cung cấp cho bạn một lỗi thời gian biên dịch.

Mặc dù vậy, tôi vẫn sẽ nhìn vào string invoice. Là một hóa đơn thực sự là một chuỗi? Có amountnghĩa là gì? Đây có nhiều khả năng là một giá trị tiền tệ.

Bạn đã đề cập trong câu hỏi của mình "những gì được gửi qua mạng chỉ là id." Điều này là chính xác, nhưng đừng để yêu cầu này làm vẩn đục tên miền của bạn.

Giải thích tốt nhất tôi từng thấy ủng hộ phương pháp này là trong quy tắc 3 của Object Calisthenics :

Một int riêng của nó chỉ là một vô hướng, vì vậy nó không có ý nghĩa. Khi một phương thức lấy một int làm tham số, tên phương thức cần thực hiện tất cả các công việc thể hiện ý định. Nếu cùng một phương thức lấy một giờ làm tham số, thì việc xem những gì đang diễn ra sẽ dễ dàng hơn nhiều. Các đối tượng nhỏ như thế này có thể giúp các chương trình dễ bảo trì hơn, vì không thể truyền Năm cho phương thức lấy tham số Giờ. Với một biến nguyên thủy, trình biên dịch không thể giúp bạn viết các chương trình chính xác về mặt ngữ nghĩa. Với một đối tượng, dù chỉ là một đối tượng nhỏ, bạn đang cung cấp cho cả trình biên dịch và lập trình viên thông tin bổ sung về giá trị là gì và tại sao nó được sử dụng.


Vì vậy, cách tiếp cận thứ hai được ưu tiên? ngay cả khi có một đối tượng câu lạc bộ chỉ với tài sản id được điền?
Mithir

Đây dường như là một blog ngẫu nhiên. Không có bằng chứng để nói những gì ưa thích. Ai quan tâm thực sự những gì ưa thích? Hãy làm những gì có ích cho bạn
James

@James Không có câu trả lời dứt khoát cho câu hỏi này, đặc biệt là vì OP đã không cho chúng ta nhiều bối cảnh. Bất cứ ai phân loại đều tuyên bố rằng một cách tiếp cận tốt hơn so với phương pháp khác là thực hiện OP một dịch vụ. Đó không phải là màu đen và trắng.
MattDavey

1
@James Tôi chỉ chỉ ra rằng cách tiếp cận đầu tiên làm cho nó rất dễ dàng để giới thiệu các lỗi khó tìm. Tôi không nói các kiểu nguyên thủy là xấu, nhưng mục đích của các kiểu nguyên thủy là xây dựng các loại miền có ý nghĩa. Sử dụng chúng bên ngoài bối cảnh này là định nghĩa của mùi mã ám ảnh nguyên thủy.
MattDavey

5
@James: Những gì MattDavey nói là một sự thật có cơ sở. Anh ta không nói rằng các kiểu bản địa là xấu, những gì anh ta nói rằng: someMethod (int, int, int, string, binary) khó hiểu và được sử dụng bởi một khách hàng hơn so với someMethod (Club, Terminal, Card, String , thập phân)
c_maker

2

Không có câu trả lời đúng cho câu hỏi này. Hoặc là tùy chọn có thể phù hợp với công việc. Gần như bằng mọi cách, đối số hóa đơn đưa ra một luống cày trên trán tôi, tôi không có manh mối gì về việc đọc mã.

Nếu bạn gửi một id, thì cả hai hệ thống cần phải được kết hợp chặt chẽ với những gì đại diện. ClubID là chìa khóa trong bảng câu lạc bộ. Hơn nữa, cả người gọi và callee đều cần phải đồng ý bảng Câu lạc bộ được gọi là gì và cơ sở dữ liệu nào. Nếu bạn không muốn hoặc không thể áp đặt ràng buộc đó, thì bạn sẽ chuyển đối tượng bằng một số mô tả chung, nguồn gốc, tuần tự hóa, xml, tên = giá trị bất cứ điều gì, một tập tin ini :)

Điều đó như bạn đã xác định sẽ khiến bạn phải trả giá "qua dây". Tránh điều đó bằng cách chỉ cần gửi định danh chi phí bạn ở nơi khác. Vì vậy, cái nào làm tổn thương bạn ít nhất, bây giờ (hoặc có thể là sau này ...) là chỉ số tốt và xấu.

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.