Có bao nhiêu tham số là quá nhiều? [đóng cửa]


228

Các thường trình có thể có các tham số, đó không phải là tin tức. Bạn có thể định nghĩa bao nhiêu tham số mà bạn có thể cần, nhưng quá nhiều trong số chúng sẽ khiến thói quen của bạn trở nên khó hiểu và duy trì.

Tất nhiên, bạn có thể sử dụng một biến có cấu trúc như một cách giải quyết: đặt tất cả các biến đó vào một cấu trúc duy nhất và chuyển nó vào thường trình. Trên thực tế, sử dụng các cấu trúc để đơn giản hóa danh sách tham số là một trong những kỹ thuật được mô tả bởi Steve McConnell trong Code Complete . Nhưng như ông nói:

Các lập trình viên cẩn thận tránh việc bó dữ liệu nhiều hơn mức cần thiết.

Vì vậy, nếu thói quen của bạn có quá nhiều tham số hoặc bạn sử dụng một cấu trúc để ngụy trang một danh sách tham số lớn, có lẽ bạn đã làm sai điều gì đó. Đó là, bạn không giữ khớp nối lỏng lẻo.

Câu hỏi của tôi là, khi tôi có thể xem xét một danh sách tham số quá lớn? Tôi nghĩ rằng hơn 5 tham số, là quá nhiều. Bạn nghĩ sao?


1
Chỉ cần tham khảo ở đây câu hỏi này là một ví dụ thực tế về việc có bao nhiêu tham số có quá nhiều ...
Gideon

5
Trong JavaScript 65537, tham số có quá nhiều: jsfiddle.net/vhmgLkdm
Aadit M Shah

Chỉ cần nhìn vào các thành phần http của apache, gần như không thể xây dựng một cái gì đó năng động từ nó
Andrew Scott Evans

Câu trả lời:


162

Khi nào một cái gì đó được coi là tục tĩu như là một cái gì đó có thể được quy định mặc dù đảm bảo sửa đổi thứ 1 để tự do ngôn luận? Theo Công lý Potter Stewart, "Tôi biết điều đó khi tôi nhìn thấy nó." Điều tương tự giữ ở đây.

Tôi ghét đưa ra các quy tắc khó và nhanh như thế này vì câu trả lời thay đổi không chỉ phụ thuộc vào quy mô và phạm vi dự án của bạn, mà tôi nghĩ rằng nó còn thay đổi theo cấp độ mô-đun. Tùy thuộc vào phương thức của bạn đang làm gì, hoặc lớp được cho là gì, đại diện cho 2 đối số là quá nhiều và là một triệu chứng của quá nhiều khớp nối.

Tôi sẽ đề nghị rằng bằng cách đặt câu hỏi ở nơi đầu tiên, và đủ điều kiện câu hỏi của bạn nhiều như bạn đã làm, rằng bạn thực sự biết tất cả những điều này. Giải pháp tốt nhất ở đây không phải là dựa vào một số khó và nhanh, mà thay vào đó hãy nhìn vào các đánh giá thiết kế và đánh giá mã giữa các đồng nghiệp của bạn để xác định các khu vực nơi bạn có sự gắn kết thấp và khớp nối chặt chẽ.

Không bao giờ sợ để cho đồng nghiệp của bạn thấy công việc của bạn. Nếu bạn sợ, đó có lẽ là dấu hiệu lớn hơn cho thấy có gì đó không đúng với mã của bạn và bạn đã biết điều đó .


Một nguyên tắc tốt là số lượng thanh ghi CPU, bởi vì nữa và trình biên dịch sẽ buộc phải phân bổ chúng trên ngăn xếp.
Michaelangel007

1
@ Michaelangel007 liên quan đến câu trả lời bạn đang bình luận bạn không nên nói điều đó, bởi vì nó nói rằng không có quy tắc. Hơn nữa, số lượng tham số là vấn đề dễ đọc, không phải hiệu suất.
clemp6r

1
@ clemp6r Không chính xác - đó là cả hai . Những người biên dịch phải đối phó với "đăng ký tràn" mọi lúc. Các chỉ thẩm quyền trả lời là để kiểm tra việc lắp ráp những gì trình biên dịch của bạn được tạo ra. Số lượng thanh ghi không thay đổi một cách kỳ diệu trên cùng một nền tảng. vi.wikipedia.org/wiki/Register_allocation
Michaelangel007

124

Một hàm chỉ có thể có quá nhiều tham số nếu một số tham số là dự phòng. Nếu tất cả các tham số được sử dụng, hàm phải có đúng số lượng tham số. Lấy chức năng này thường được sử dụng:

HWND CreateWindowEx
(
  DWORD dwExStyle,
  LPCTSTR lpClassName,
  LPCTSTR lpWindowName,
  DWORD dwStyle,
  int x,
  int y,
  int nWidth,
  int nHeight,
  HWND hWndParent,
  HMENU hMenu,
  HINSTANCE hInstance,
  LPVOID lpParam
);

Đó là 12 tham số (9 nếu bạn bó x, y, w và h thành một hình chữ nhật) và cũng có các tham số xuất phát từ tên lớp. Làm thế nào bạn sẽ giảm điều này? Bạn có muốn giảm số lượng nhiều hơn đến điểm?

Đừng để số lượng tham số làm phiền bạn, chỉ cần đảm bảo rằng nó hợp lý và được ghi chép đầy đủ và để intellisense * giúp bạn.

* Trợ lý mã hóa khác có sẵn!


37
Tôi đang bỏ phiếu này. Tôi ngạc nhiên trước tất cả các câu trả lời khác nói "3" và "4"! Câu trả lời đúng là: mức tối thiểu cần thiết, đôi khi có thể khá ít.
Tony Andrew

16
Nếu chức năng đó được thiết kế ngày hôm nay thì có lẽ nó sẽ hơi khác một chút. x, y, nWidth và nHeight có thể được gói trong một đối tượng Hình chữ nhật. style và xStyle có thể được kết hợp thành một tập hợp các enum hoặc chuỗi. Bây giờ bạn chỉ có 8 tham số.
vây

16
@finnw Nếu chức năng đó được thiết kế ngày hôm nay? Nó đã được thiết kế lại. Mẫu f = Mẫu mới (); có 0 tham số.
Nick

36
Đây là C winapi. Tôi không thể nghĩ ra một ví dụ tồi tệ hơn.
L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳

17
Không không. Đây là phong cách thủ tục. Windows là đối tượng, vì vậy đây là lỗi thời. Ngày nay, điều này sẽ được giải quyết với các lớp tổng hợp, không phải với các tham số. Quy tắc trực quan của thiết kế tốt là nếu bạn không thể mô tả chức năng (bao gồm các tham số) trong một câu đơn giản, thì nó được thiết kế kém . Tôi tin rằng đây là trường hợp.
Jan Turoň

106

Trong Clean Code , Robert C. Martin dành bốn trang cho chủ đề này. Đây là ý chính:

Số lượng đối số lý tưởng cho một hàm là 0 (niladic). Tiếp đến là một (monadic), theo sát bởi hai (dyadic). Nên tránh ba đối số (bộ ba) nếu có thể. Hơn ba (polyadic) đòi hỏi sự biện minh rất đặc biệt - và sau đó không nên sử dụng.


2
Tôi nghi ngờ nó bao gồm "điều này" bởi vì đó là bối cảnh thực hiện. Trong lập trình chức năng, bối cảnh là toàn cầu và trong oop, bối cảnh là đối tượng mà bạn đang áp dụng phương thức. Ngoài ra, nếu bạn bao gồm "cái này" trong danh sách tham số, thì không thể có 0 params (lý tưởng).
Tom

1
Không, nó không bao gồm "cái này."
Patrick McElhaney

20
Hơn nữa, Martin nên có một lời với ủy ban tiêu chuẩn C ++. Một nửa <thuật toán> mất hơn 3 tham số, vì chỉ cần một phạm vi lặp là 2. Đó chỉ là bản chất của lập trình với các trình vòng lặp (tức là lập trình chung với các bộ sưu tập STL).
Steve Jessop

3
@SteveJessop: lỗi của <Thuật toán> là nó luôn hoạt động trên một lát. Nếu thuật toán và bộ sưu tập được thiết kế lại, tôi sẽ làm cho các thuật toán luôn mất toàn bộ bộ sưu tập và bạn sẽ có cách cắt một khung nhìn của một bộ sưu tập để cho phép các thuật toán hoạt động trên các phần; cách khác, tôi cũng xác định ghi đè tốc ký để dễ dàng xử lý trong trường hợp chung.
Lie Ryan

3
@LieRyan: trong khi nếu tôi đang thiết kế lại thì <algorithm>tôi sẽ hành động trên một đối tượng phạm vi. Bộ sưu tập sẽ là phạm vi, nhưng không phải tất cả các phạm vi sẽ là bộ sưu tập. Và thực sự, boost đã làm được điều đó rồi. Dù sao, quan điểm của tôi là một thư viện được sử dụng rộng rãi đã bỏ qua lời khuyên này, vì vậy điều tồi tệ nhất được đảm bảo sẽ xảy ra với bạn nếu bạn cũng vậy, đó là hàng triệu người dùng của bạn sẽ sửa đổi các giao diện đơn giản của bạn ;-)
Steve Jessop

79

Một số mã tôi đã làm việc trong quá khứ đã sử dụng các biến toàn cục chỉ để tránh truyền quá nhiều tham số xung quanh.

Xin đừng làm vậy!

(Thông thường.)


Một số mã tôi đang làm việc trên các thành viên lớp đã sử dụng để đạt được điều tương tự. Lúc đó tôi là một lập trình viên C và tôi đã hỏi, tại sao có quá nhiều biến toàn cục, tại sao đầu vào / đầu ra không thể là tham số rõ ràng?
dùng3528438

38

Nếu bạn bắt đầu phải đếm ngược các tham số trong chữ ký và khớp chúng với cuộc gọi, thì đã đến lúc tái cấu trúc!


Đó là một câu trả lời rất tốt. Nếu các tham số được tổ chức hợp lý (x, y, w, h), thật dễ dàng để nhớ tất cả chúng theo đúng thứ tự. Thật khó khăn hơn để xác định vị trí đặt con trỏ FILE trong putc (chỉ có hai tham số), đặc biệt là vì fprintf thì ngược lại.
dùng877329

Câu trả lời hay nhất. Nói rất hay
Anwar

31

Cảm ơn bạn rất nhiều vì tất cả các câu trả lời của bạn:

  • Có một chút ngạc nhiên khi tìm thấy những người cũng nghĩ (như tôi) rằng 5 tham số là một giới hạn tốt cho sự tỉnh táo của mã.

  • Nói chung, mọi người có xu hướng đồng ý rằng giới hạn giữa 3 và 4 là quy tắc tốt. Điều này là hợp lý vì mọi người thường có một thời gian tồi tệ đếm hơn 4 điều.

  • Như Milan chỉ ra , trung bình mọi người có thể giữ ít nhất 7 thứ trong đầu. Nhưng tôi nghĩ rằng bạn không thể quên rằng, khi bạn đang thiết kế / duy trì / nghiên cứu một thói quen, bạn phải ghi nhớ nhiều thứ hơn là chỉ các tham số.

  • Một số người cho rằng một thói quen nên có nhiều tranh luận như nó cần. Tôi đồng ý, nhưng chỉ trong một vài trường hợp cụ thể (gọi API hệ điều hành, các thói quen trong đó tối ưu hóa là quan trọng, v.v.). Tôi đề nghị che giấu sự phức tạp của các thói quen này bằng cách thêm một lớp trừu tượng ngay phía trên các cuộc gọi này bất cứ khi nào có thể.

  • Nickmột vài suy nghĩ thú vị về điều này. Nếu bạn không muốn đọc bình luận của anh ấy, tôi tóm tắt cho bạn: tóm lại, điều đó phụ thuộc vào :

    Tôi ghét đưa ra các quy tắc khó và nhanh như thế này vì câu trả lời thay đổi không chỉ phụ thuộc vào quy mô và phạm vi dự án của bạn, mà tôi nghĩ rằng nó còn thay đổi theo cấp độ mô-đun. Tùy thuộc vào phương thức của bạn đang làm gì, hoặc lớp được cho là gì, đại diện cho 2 đối số là quá nhiều và là một triệu chứng của quá nhiều khớp nối.

    Đạo đức ở đây là không sợ hiển thị mã của bạn cho các đồng nghiệp của bạn, thảo luận với họ và cố gắng "xác định các khu vực nơi bạn có sự gắn kết thấp và khớp nối chặt chẽ" .

  • Cuối cùng, tôi nghĩ rằng wnoise rất đồng ý với Nick, và kết luận đóng góp châm biếm của anh ấy với tầm nhìn đầy chất thơ này (xem bình luận bên dưới) về nghệ thuật lập trình:

    Lập trình không phải là kỹ thuật. Tổ chức mã là một nghệ thuật vì nó phụ thuộc vào các yếu tố con người, nó phụ thuộc quá nhiều vào bối cảnh cho bất kỳ quy tắc cứng nào.


16

Câu trả lời này giả sử một ngôn ngữ OO. Nếu bạn không sử dụng một - hãy bỏ qua câu trả lời này (đây không hoàn toàn là câu trả lời không thể biết bằng ngôn ngữ.

Nếu bạn truyền nhiều hơn 3 tham số (đặc biệt là các loại / đối tượng nội tại), thì đó không phải là "Quá nhiều" mà là bạn có thể bỏ lỡ cơ hội tạo đối tượng mới.

Tìm kiếm các nhóm tham số được truyền vào nhiều hơn một phương thức - thậm chí một nhóm được truyền vào hai phương thức gần như đảm bảo rằng bạn nên có một đối tượng mới ở đó.

Sau đó, bạn cấu trúc lại chức năng vào đối tượng mới của mình và bạn sẽ không tin nó giúp được cả mã của bạn và sự hiểu biết của bạn về lập trình OO.


Xin vui lòng, đặt tên cho một ngôn ngữ không sử dụng thường trình cũng như tham số. Tôi không thể nghĩ về một, thậm chí lắp ráp có thể được coi là có thói quen (nhãn).
Auron

lắp ráp x86 chắc chắn có thói quen (gọi / trả lại). Những người khác có thể yêu cầu combo cmp / jmp.
Brian Knoblauch

Xin lỗi, "ret", không "trở lại". Thở dài. Đó là một ngày dài.
Brian Knoblauch

Xin lỗi về cụm từ mơ hồ Auron, tôi tin rằng tôi đã sửa nó. Đó là câu trả lời của tôi là ngôn ngữ cụ thể, không phải câu hỏi.
Bill K

1
Không phải tất cả các ngôn ngữ cho phép vượt qua các cấu trúc. Ngoài ra, truyền một cấu trúc có nghĩa là phương thức nhận phải có mã để xử lý cấu trúc và do đó, có thể cần nhiều tham số hơn. Ngoài ra, trong ngôn ngữ không phải là oo, bạn thường cần một tham số phụ - tất cả các ngôn ngữ OO đều có tham số "Ẩn" của "điều này" mà nếu không được truyền vào (hoặc, trong một ngôn ngữ / thiết kế khủng khiếp hơn, có thể trên toàn cầu có thể truy cập)
Bill K

13

Có vẻ như có những cân nhắc khác ngoài con số đơn thuần, đây là một số điều mà tôi nghĩ đến:

  1. mối quan hệ logic với mục đích chính của chức năng so với cài đặt một lần

  2. Nếu chúng chỉ là cờ môi trường, thì gói có thể rất tiện dụng


12

Một trong những epigram lập trình nổi tiếng của Alan Perlis (được kể lại trong ACM SIGPLAN Thông báo 17 (9), tháng 9, 1982) nói rằng "Nếu bạn có một quy trình với 10 tham số, có lẽ bạn đã bỏ lỡ một số."



9

Đối với tôi, khi danh sách vượt qua một dòng trên IDE của tôi, thì đó là một tham số quá nhiều. Tôi muốn xem tất cả các tham số trong một dòng mà không phá vỡ giao tiếp bằng mắt. Nhưng đó chỉ là sở thích cá nhân của tôi.


Điều này là tốt cho đến khi bạn với một số nhà phát triển sẽ thử foo (int a, float b, chuỗi c, double d). Tôi đoán tốt nhất để tránh làm việc với họ. : D
Rontologist

4
Nếu ai đó đã đưa ra các lớp tên dài một cách lố bịch, tôi sẽ không để điều đó ảnh hưởng đến cách tôi xác định hoặc gọi các thói quen của mình.
vây

9
Tôi có thể giới thiệu cho bạn "xe trở về" không?

3
Khi danh sách vượt qua một dòng trên IDE của bạn, thì màn hình của bạn quá nhỏ để sử dụng nó với mã đó và rõ ràng bạn nên mua một màn hình có độ phân giải ngang cao hơn. Việc ngắt dòng hoặc giảm số lượng tham số chỉ là cách giải quyết không giải quyết được vấn đề gốc là màn hình của bạn quá nhỏ so với cơ sở mã đó!
Kaiserludi

9

Tôi thường đồng ý với 5, tuy nhiên, nếu có một tình huống tôi cần nhiều hơn và đó là cách rõ ràng nhất để giải quyết vấn đề, thì tôi sẽ sử dụng nhiều hơn.


8

Bảy điều trong trí nhớ ngắn hạn?

  1. Tên của hàm
  2. Giá trị trả về của hàm
  3. Mục đích của chức năng
  4. Tham số 1
  5. Thông số 2
  6. Thông số 3
  7. Thông số 4

Tốt. Đó là một quy tắc của ngón tay cái. Khi bạn đang mã hóa phần thân của một hàm, bạn không quan tâm đến tên của nó và giá trị trả về và mục đích của nó có liên quan chặt chẽ với nhau.
Auron

7
8. thứ tự của các tham số
Eva

7

Trong 5 Đoạn mã tệ nhất , hãy kiểm tra cái thứ hai, "Đây có phải là hàm tạo không". Nó có hơn 37 4 ≈ 150 tham số:

Ở đây, một lập trình viên đã viết hàm tạo này [... S] ome bạn có thể nghĩ rằng đó là một hàm tạo lớn nhưng anh ta đã sử dụng các công cụ tạo mã tự động nhật thực [.] NOO, trong hàm tạo này có một lỗi nhỏ mà tôi phát hiện ra, khiến tôi phát hiện ra kết luận rằng hàm tạo này được viết bằng tay. (bằng cách này chỉ là phần trên cùng của hàm tạo, nó không hoàn chỉnh).

hàm tạo với hơn 150 tham số


Điều này thật đáng buồn ... Không biết về "bản ghi" hoặc "cấu trúc" hoặc "đối tượng giá trị", kết hợp nhiều giá trị lại với nhau và đặt cho chúng một tên chung để bạn có thể phân cấp nhiều thứ theo cách dễ đọc giống như đi bộ xung quanh với đôi giày không có dây trong nhiều năm bởi vì không ai từng nói với bạn rằng bạn thậm chí có thể làm điều đó
yeoman

6

Một nhiều hơn cần thiết. Tôi không có nghĩa là vui vẻ, nhưng có một số chức năng nhất thiết cần khá nhiều tùy chọn. Ví dụ:

void *
mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t offset);

Có 6 đối số, và mỗi một trong số chúng là cần thiết. Hơn nữa, không có liên kết chung giữa chúng để biện minh cho việc bó chúng. Có lẽ bạn có thể định nghĩa "struct mmapargs", nhưng điều đó sẽ tồi tệ hơn.


Chà, protflagscó thể đã được cuộn lại với nhau nếu nhà thiết kế cảm thấy rằng 5 bằng cách nào đó là một con số ma thuật tốt hơn nhiều so với 6. Một chút giống như cách openkết hợp chế độ đọc / ghi với tất cả các cờ linh tinh khác. Và có lẽ bạn có thể thoát khỏi offsetbằng cách chỉ định rằng phần được ánh xạ bắt đầu ở vị trí tìm kiếm hiện tại của filedes. Tôi không biết có bất kỳ tình huống nào mà bạn có thể ở mmapmột khu vực mà bạn không có khả năng tiếp cận hay không lseek, nhưng nếu không thì điều đó không thực sự cần thiết.
Steve Jessop

... vì vậy tôi nghĩ mmaplà một minh họa tốt cho thực tế rằng một số nhà thiết kế và người dùng thích một danh sách dài các tham số, trong khi những người khác thích trải qua một vài bước chuẩn bị số lượng tham số nhỏ hơn trước khi thực hiện cuộc gọi.
Steve Jessop

1
@Steve: Đặt vị trí tìm kiếm bằng một cuộc gọi riêng trước đó sẽ đưa ra một điều kiện cuộc đua vô cớ. Đối với một số API (OpenGL), có rất nhiều tham số ảnh hưởng đến cuộc gọi mà bạn thực sự phải sử dụng trạng thái, nhưng thông thường, mọi cuộc gọi nên đứng một mình càng nhiều càng tốt. Hành động ở một khoảng cách là con đường đến phía tối.
Ben Voigt

5

Dựa theo Perl Best Practice , 3 là được, 4 là quá nhiều. Đó chỉ là một hướng dẫn, nhưng trong cửa hàng của chúng tôi đó là những gì chúng tôi cố gắng bám vào.


5

Tôi sẽ tự giới hạn các hàm công khai ở 5 tham số.

IMHO, danh sách tham số dài chỉ được chấp nhận trong các hàm trợ giúp riêng / cục bộ chỉ được gọi từ một vài vị trí cụ thể trong mã. Trong những trường hợp đó, bạn có thể cần chuyển nhiều thông tin trạng thái cùng, nhưng khả năng đọc không phải là vấn đề đáng lo ngại vì chỉ bạn (hoặc ai đó sẽ duy trì mã của bạn và nên hiểu các nguyên tắc cơ bản của mô-đun của bạn) phải quan tâm gọi chức năng đó.


Mà chính xác là tại sao nhiều người tại thời điểm này sẽ tạo ra mọi thứ không phải là một đối số thực tế, nhưng trạng thái mang theo, chỉ là trạng thái của một đối tượng ở dạng trường (biến thành viên). Đối tượng đó sẽ được đại diện như một lớp. Nó sẽ được khởi tạo một lần hoặc cho mỗi lần sử dụng. Đôi khi một đối tượng như vậy sẽ chỉ có một gói phương thức riêng tư hoặc công khai, sau đó các đại biểu làm việc với các phương thức riêng tư với một vài đối số. Rất ít đối số hiện có thể vì cấu hình và trạng thái hiện có một vị trí thích hợp :)
yeoman

5

Một câu hỏi liên quan bạn nên xem xét là mức độ gắn kết của thói quen. Một số lượng lớn các tham số có thể là một mùi cho bạn biết rằng chính thói quen đó đang cố gắng làm quá nhiều và do đó, sự gắn kết là nghi ngờ. Tôi đồng ý rằng số lượng tham số cứng và nhanh có lẽ là không thể nhưng tôi đoán rằng một thói quen gắn kết cao sẽ ngụ ý số lượng tham số thấp.



4

Tôi dừng lại ở ba tham số như một quy tắc chung. Thay vào đó, đã đến lúc phải vượt qua một loạt các tham số hoặc một đối tượng cấu hình, điều này cũng cho phép các tham số trong tương lai được thêm vào mà không thay đổi API.


Nếu API thay đổi, thì API thực sự sẽ thay đổi, không chỉ có thay đổi lén lút mà sự không tương thích vẫn có thể xảy ra, nhưng ít rõ ràng hơn.
wnoise

tuy nhiên, nếu bạn cần thêm một tham số để định cấu hình trường hợp cạnh, nó không nên lan truyền đến các thành phần không liên quan bằng API
Eran Galperin

4

Giới hạn độ dài trên danh sách tham số chỉ là một hạn chế nữa. Và hạn chế có nghĩa là bạo lực áp dụng. Nghe có vẻ buồn cười, nhưng bạn có thể không bạo lực ngay cả khi lập trình. Chỉ cần để mã ra lệnh. Rõ ràng là nếu bạn có nhiều tham số, phần thân của phương thức hàm / lớp sẽ đủ lớn để sử dụng chúng. Và các đoạn mã lớn thường có thể được cấu trúc lại và chia thành các phần nhỏ hơn. Vì vậy, bạn nhận được giải pháp chống lại việc có nhiều tham số là phần thưởng miễn phí, vì chúng được phân chia giữa các đoạn mã được tái cấu trúc nhỏ hơn.


4

Một điều tôi muốn chỉ ra từ góc độ hiệu năng là tùy thuộc vào cách bạn truyền tham số cho một phương thức, việc truyền nhiều tham số theo giá trị sẽ làm chậm chương trình vì mỗi tham số phải được sao chép và sau đó được đặt trên ngăn xếp.

Sử dụng một lớp duy nhất để bao gồm tất cả các tham số sẽ hoạt động tốt hơn bởi vì một tham số được truyền bởi tham chiếu sẽ thanh lịch và sạch sẽ hơn và nhanh hơn!


Tôi đưa ra câu trả lời này là +1 vì đây là câu hỏi duy nhất thảo luận về bất cứ điều gì ngoài độ sạch mã hoặc giới hạn tùy ý, cả hai đều chủ quan. Một số người có thể không nghĩ về những gì bạn đang làm với ngăn xếp khi bạn ở trong một vòng lặp và đẩy hàng tá đối số vào và ra khỏi ngăn xếp. Nếu đó là một vòng lặp, bạn nên cân nhắc sử dụng số lượng đối số được ĐĂNG KÝ thông qua trong ABI mà bạn đang biên dịch. Ví dụ: trong MS x64 ABI, max args đã vượt qua các thanh ghi thông qua là 4. "System V" ABI (được sử dụng bởi hệ điều hành không phải Windows) sử dụng nhiều thanh ghi hơn, vì vậy sử dụng 4 args khá di động
Lakey

3

Theo tôi có thể có trường hợp bạn sẽ vượt quá 4 hoặc một số số cố định. Những điều cần chú ý có thể là

  1. Phương pháp của bạn đang làm quá nhiều và bạn cần cấu trúc lại.
  2. Bạn có thể muốn xem xét sử dụng một bộ sưu tập hoặc một số cấu trúc dữ liệu.
  3. Xem xét lại thiết kế lớp học của bạn, có thể một số điều không cần phải được thông qua.

Từ góc độ dễ sử dụng hoặc dễ đọc mã, tôi nghĩ rằng khi bạn cần loại "chữ bọc" chữ ký phương thức của mình, điều đó sẽ khiến bạn dừng lại và suy nghĩ, Trừ khi bạn cảm thấy bất lực và mọi nỗ lực làm cho chữ ký nhỏ hơn dẫn đến không kết quả. Một số thư viện rất tốt trong quá khứ và hiện tại sử dụng hơn 4-5 prams.


3

Nguyên tắc nhỏ của tôi là tôi cần có khả năng nhớ các thông số đủ lâu để xem một cuộc gọi và cho biết nó làm gì. Vì vậy, nếu tôi không thể nhìn vào phương thức và sau đó chuyển sang một cuộc gọi của phương thức và nhớ tham số nào làm gì thì có quá nhiều.

Đối với tôi tương đương với khoảng 5, nhưng tôi không sáng đến thế. Số dặm của bạn có thể thay đổi.

Bạn có thể tạo một đối tượng với các thuộc tính để giữ các tham số và chuyển nó vào nếu bạn vượt quá bất kỳ giới hạn nào bạn đặt. Xem cuốn sách Tái cấu trúc của Martin Fowler và chương về cách gọi phương thức đơn giản hơn.


1

Nó phụ thuộc rất nhiều vào môi trường bạn đang làm việc. Lấy ví dụ javascript. Trong javascript, cách tốt nhất để truyền tham số là sử dụng các đối tượng có cặp khóa / giá trị, trong thực tế có nghĩa là bạn chỉ có một tham số. Trong các hệ thống khác, điểm ngọt sẽ ở ba hoặc bốn.

Cuối cùng, tất cả sôi sục theo sở thích cá nhân.


1

Tôi sẽ đồng ý với 3 là được, 4 là quá nhiều như một hướng dẫn. Với hơn 3 tham số, chắc chắn bạn sẽ thực hiện nhiều hơn một nhiệm vụ. Nhiều hơn một nhiệm vụ nên được chia thành các phương thức riêng biệt.

Tuy nhiên, nếu tôi xem xét dự án mới nhất mà tôi đã làm, các ngoại lệ sẽ rất nhiều và hầu hết các trường hợp sẽ khó có thể giảm xuống còn 3 tham số.


1

Nếu tôi có 7-10 tham số trong một thói quen, tôi sẽ xem xét việc bó chúng vào một lớp mới nhưng không phải nếu lớp đó sẽ không là gì ngoài một loạt các trường có getters và setters - lớp mới phải làm một cái gì đó ngoài các giá trị xáo trộn trong và ngoài. Nếu không, tôi muốn đưa ra danh sách tham số dài.


1
Tôi sẽ gói nó với một lớp chỉ có dữ liệu nếu nó được sử dụng ở nhiều nơi, nhưng thậm chí sau đó tôi thường tạo cả hai hàm tạo.
Leahn Novash

1

Một sự thật được biết đến là, trung bình, mọi người có thể giữ 7 +/- 2 thứ trong đầu một lúc. Tôi thích sử dụng nguyên tắc đó với các tham số. Giả sử rằng các lập trình viên đều là những người thông minh trên trung bình, tôi sẽ nói mọi thứ 10+ là quá nhiều.

BTW, nếu các tham số tương tự nhau theo bất kỳ cách nào, tôi sẽ đặt chúng vào một vectơ hoặc danh sách thay vì cấu trúc hoặc lớp.


1

Tôi sẽ căn cứ vào câu trả lời của mình về tần suất gọi hàm.

Nếu đó là một hàm init chỉ được gọi một lần thì hãy để nó mất 10 parms trở lên, ai quan tâm.

Nếu nó được gọi là một bó thời gian trên mỗi khung thì tôi có xu hướng tạo cấu trúc và chỉ truyền một con trỏ cho nó vì nó có xu hướng nhanh hơn (giả sử rằng bạn cũng không xây dựng lại cấu trúc mỗi lầ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.