พารามิเตอร์มีจำนวนมากเกินไป [ปิด]


228

กิจวัตรสามารถมีพารามิเตอร์ได้นั่นไม่ใช่ข่าวเลย คุณสามารถกำหนดพารามิเตอร์ได้มากเท่าที่คุณต้องการ แต่มีจำนวนมากเกินไปที่จะทำให้งานประจำของคุณยากที่จะเข้าใจและบำรุงรักษา

แน่นอนคุณสามารถใช้ตัวแปรที่มีโครงสร้างเป็นวิธีแก้ไข: วางตัวแปรเหล่านั้นทั้งหมดไว้ในโครงสร้างเดียวและส่งผ่านไปยังรูทีน ในความเป็นจริงโดยใช้โครงสร้างที่จะลดความซับซ้อนของรายการพารามิเตอร์เป็นหนึ่งในเทคนิคที่อธิบายไว้โดยสตีฟ McConnell ในรหัสเสร็จสมบูรณ์ แต่ในขณะที่เขาพูดว่า:

โปรแกรมเมอร์อย่างระมัดระวังหลีกเลี่ยงการรวมข้อมูลมากกว่าที่จำเป็นตามหลักเหตุผล

ดังนั้นถ้ารูทีนของคุณมีพารามิเตอร์มากเกินไปหรือคุณใช้ struct เพื่อปิดบังรายการพารามิเตอร์ขนาดใหญ่คุณอาจทำอะไรผิดพลาด นั่นคือคุณไม่ได้มีเพศสัมพันธ์หลวม

คำถามของฉันคือเมื่อใดที่ฉันสามารถพิจารณารายการพารามิเตอร์ที่ใหญ่เกินไป ฉันคิดว่าพารามิเตอร์มากกว่า 5 ตัวนั้นมากเกินไป คุณคิดอย่างไร?


1
เพียงแค่อ้างถึงคำถามนี้ซึ่งเป็นตัวอย่างที่ใช้งานได้จริงของจำนวนพารามิเตอร์ที่มากเกินไป ...
Gideon

5
ในพารามิเตอร์ JavaScript 65537 มีจำนวนมากเกินไป: jsfiddle.net/vhmgLkdm
Aadit M Shah

เพียงแค่มองส่วนประกอบ Apache http มันเป็นไปไม่ได้เกือบที่จะสร้างบางสิ่งบางอย่างแบบไดนามิกออกจากมัน
แอนดรูสกอตต์อีแวนส์

คำตอบ:


162

เมื่อใดที่มีการพิจารณาเรื่องลามกอนาจารว่าเป็นสิ่งที่สามารถควบคุมได้แม้จะมีการรับประกันการแก้ไขครั้งที่ 1 ในการพูดฟรี? ผู้พิพากษาพอตเตอร์สจ๊วตอ้างอิงจากส "ฉันรู้ว่าเมื่อฉันเห็นมัน" เช่นเดียวกันถือที่นี่

ฉันเกลียดการสร้างกฎที่ยากและรวดเร็วเช่นนี้เพราะคำตอบไม่เพียง แต่เปลี่ยนไปขึ้นอยู่กับขนาดและขอบเขตของโครงการของคุณ แต่ฉันคิดว่ามันเปลี่ยนไปถึงระดับโมดูล ขึ้นอยู่กับว่าวิธีการของคุณกำลังทำอยู่หรือคลาสใดควรเป็นตัวแทนมันเป็นไปได้มากที่การโต้แย้ง 2 ข้อนั้นมากเกินไปและเป็นอาการของการมีเพศสัมพันธ์มากเกินไป

ฉันขอแนะนำว่าโดยการถามคำถามในตอนแรกและมีคุณสมบัติคำถามเท่าที่คุณทำคุณรู้ทั้งหมดนี้จริง ๆ ทางออกที่ดีที่สุดที่นี่ไม่ได้ขึ้นอยู่กับจำนวนที่แข็งและเร็ว แต่ให้มองไปที่บทวิจารณ์การออกแบบและบทวิจารณ์โค้ดในหมู่เพื่อน ๆ ของคุณเพื่อระบุพื้นที่ที่คุณมีการเชื่อมต่อที่ต่ำและคับปลิ้งคับ

อย่ากลัวที่จะแสดงให้เพื่อนร่วมงานเห็นถึงผลงานของคุณ หากคุณมีความกลัวที่จะว่าน่าจะเป็นสัญญาณที่ใหญ่กว่าว่ามีอะไรบางอย่างผิดปกติกับรหัสของคุณและที่คุณรู้อยู่แล้วว่ามัน


กฎข้อหนึ่งที่ดีคือจำนวนการลงทะเบียน CPU เพราะอีกต่อไปและคอมไพเลอร์จะถูกบังคับให้จัดสรรมันในสแต็ก
Michaelangel007

1
@ Michaelangel007 เกี่ยวกับคำตอบที่คุณแสดงความคิดเห็นคุณไม่ควรพูดอย่างนั้นเพราะมันบอกว่าไม่มีกฎ นอกจากนี้จำนวนของพารามิเตอร์เป็นเรื่องของการอ่านไม่ได้ประสิทธิภาพ
clemp6r

1
@ clemp6r ที่ไม่ถูกต้อง - มันเป็นทั้ง พวกคอมไพเลอร์ต้องจัดการกับ "register spill" ตลอดเวลา เพียงคำตอบเผด็จการคือการตรวจสอบการชุมนุมของสิ่งที่คอมไพเลอร์ของคุณคือการสร้าง จำนวนการลงทะเบียนไม่เปลี่ยนแปลงอย่างน่าอัศจรรย์บนแพลตฟอร์มเดียวกัน en.wikipedia.org/wiki/Register_allocation
Michaelangel007

124

ฟังก์ชั่นสามารถมีพารามิเตอร์มากเกินไปหากพารามิเตอร์บางตัวซ้ำซ้อน หากใช้พารามิเตอร์ทั้งหมดฟังก์ชันจะต้องมีจำนวนพารามิเตอร์ที่ถูกต้อง ใช้ฟังก์ชันที่ใช้บ่อยนี้:

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
);

นั่นคือ 12 พารามิเตอร์ (9 ถ้าคุณรวม x, y, w และ h เป็นรูปสี่เหลี่ยมผืนผ้า) และยังมีพารามิเตอร์ที่มาจากชื่อคลาสด้วย คุณจะลดสิ่งนี้ได้อย่างไร คุณต้องการลดจำนวนลงหรือไม่?

อย่าปล่อยให้จำนวนพารามิเตอร์รบกวนคุณเพียงตรวจสอบให้แน่ใจว่ามันมีเหตุผลและมีเอกสารที่ดีและให้ Intellisense *ช่วยคุณได้

*มีผู้ช่วยการเข้ารหัสอื่น ๆ !


37
ฉันลงคะแนนให้ ฉันประหลาดใจที่คำตอบอื่น ๆ ทั้งหมดพูดว่า "3" และ "4"! คำตอบที่ถูกต้องคือ: ขั้นต่ำที่จำเป็นซึ่งบางครั้งอาจเป็นจำนวนน้อย
Tony Andrews

16
ถ้าฟังก์ชั่นนั้นได้รับการออกแบบมาในวันนี้มันอาจจะดูแตกต่างออกไปเล็กน้อย x, y, n ความกว้างและ nHeight สามารถรวมในวัตถุสี่เหลี่ยมผืนผ้า สไตล์และ xStyle สามารถรวมกันเป็นชุดของ enums หรือสตริง ตอนนี้คุณมีเพียง 8 พารามิเตอร์
finnw

16
@finnw ถ้าฟังก์ชั่นนั้นได้รับการออกแบบในวันนี้? มันได้รับการออกแบบใหม่แล้ว แบบฟอร์ม f = แบบฟอร์มใหม่ (); มี 0 พารามิเตอร์
นิค

36
นี่คือ C และ winapi ฉันไม่สามารถคิดถึงตัวอย่างที่แย่กว่านั้นได้
L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳

17
ไม่ไม่. นี่คือรูปแบบขั้นตอน Windows เป็นวัตถุดังนั้นนี่จึงล้าสมัยแล้ว วันนี้สิ่งนี้จะได้รับการแก้ไขด้วยคลาสที่รวมเข้าด้วยกันไม่ใช่ด้วยพารามิเตอร์จำนวนมาก กฎที่ใช้งานง่ายของการออกแบบที่ดีคือถ้าคุณไม่สามารถอธิบายฟังก์ชัน (รวมทั้งพารามิเตอร์) ในประโยคง่ายๆมันถูกออกแบบมาไม่ดี ฉันเชื่อว่าเป็นกรณีนี้
Jan Turoň

106

ในรหัสสะอาดโรเบิร์ตซี. มาร์ตินอุทิศสี่หน้าให้กับเรื่อง นี่คือส่วนสำคัญ:

จำนวนอาร์กิวเมนต์ที่เหมาะสมที่สุดสำหรับฟังก์ชันคือศูนย์ (niladic) ถัดไปมาหนึ่ง (monadic) ตามมาด้วยสอง (dyadic) ควรหลีกเลี่ยงการโต้เถียงสามครั้ง (triadic) หากเป็นไปได้ มากกว่าสาม (polyadic) ต้องมีเหตุผลพิเศษมาก - และไม่ควรใช้ต่อไป


2
ฉันสงสัยว่ามันรวมถึง "สิ่งนี้" เพราะนั่นคือบริบทของการดำเนินการ ในการเขียนโปรแกรมเชิงปฏิบัติบริบทเป็นของโลกและในบริบทของ OOP บริบทนั้นเป็นวัตถุที่คุณใช้วิธีนั้น นอกจากนี้หากคุณรวม "this" ไว้ในรายการพารามิเตอร์จะเป็นไปไม่ได้ที่จะมี 0 params (อุดมคติ)
ทอม

1
ไม่ไม่รวม "สิ่งนี้"
Patrick McElhaney

20
นอกจากนี้มาร์ตินควรมีคำพูดกับคณะกรรมการมาตรฐาน C ++ <algorithm> ครึ่งหนึ่งใช้พารามิเตอร์มากกว่า 3 ตัวเนื่องจากมีเพียงหนึ่งช่วงตัววนซ้ำที่เป็น 2 แล้ว เป็นเพียงลักษณะของการเขียนโปรแกรมด้วยตัววนซ้ำ (เช่นการเขียนโปรแกรมทั่วไปกับคอลเลกชัน STL)
Steve Jessop

3
@SteveJessop: ความผิดของ <algorithm> คือมันทำงานบนชิ้นงานเสมอ หากอัลกอริทึมและคอลเลกชันได้รับการออกแบบใหม่ฉันจะทำให้อัลกอริทึมใช้การรวบรวมทั้งหมดเสมอและคุณจะได้รับวิธีการแบ่งมุมมองของคอลเลกชันเพื่อให้อัลกอริทึมทำงานในส่วนต่างๆ อีกทางหนึ่งฉันจะกำหนดการเขียนชวเลขเพื่อให้ง่ายต่อการทำงานในกรณีทั่วไป
Lie Ryan

3
@LieRyan: ในขณะที่ถ้าฉันได้รับการออกแบบใหม่<algorithm>ฉันจะให้มันทำหน้าที่เป็นวัตถุช่วง คอลเลกชันจะเป็นช่วง แต่ไม่ใช่ทุกช่วงจะเป็นคอลเลกชัน และแน่นอนว่าการส่งเสริมได้ทำไปแล้ว อย่างไรก็ตามจุดของฉันคือการที่ห้องสมุดอย่างหนาแน่นใช้กันอย่างแพร่หลายไม่สนใจคำแนะนำนี้เพื่อที่เลวร้ายที่สุดที่รับประกันที่จะเกิดขึ้นกับคุณถ้าคุณทำเกินไปก็คือว่าหลายล้านผู้ใช้ของคุณจะจรจัดกับ simplifications เล็กน้อยอินเตอร์เฟซของคุณ ;-)
สตีฟ Jessop

79

บางรหัสที่ฉันเคยทำงานด้วยในอดีตใช้ตัวแปรทั่วโลกเพียงเพื่อหลีกเลี่ยงการส่งพารามิเตอร์มากเกินไป

โปรดอย่าทำอย่างนั้น!

(ปกติ.)


รหัสบางอย่างที่ฉันใช้กับสมาชิกชั้นเรียนใช้เพื่อให้ได้สิ่งเดียวกัน ในเวลานั้นฉันเป็นโปรแกรมเมอร์ C และถามว่าทำไมถึงมีตัวแปรทั่วโลกมากมายทำไมพารามิเตอร์อินพุต / เอาต์พุตไม่สามารถเป็นพารามิเตอร์ได้อย่างชัดเจน
3528438

38

หากคุณเริ่มต้นที่จะต้องนับจิตใจพารามิเตอร์ในลายเซ็นและจับคู่พวกเขากับการโทรแล้วก็ถึงเวลาที่จะ refactor!


นั่นเป็นคำตอบที่ดีมาก หากพารามิเตอร์มีการจัดระเบียบอย่างมีเหตุผล (x, y, w, h) มันง่ายที่จะจดจำพารามิเตอร์ทั้งหมดในลำดับที่ถูกต้อง มันยากมากที่จะจำที่วางตัวชี้ไฟล์ใน putc (ซึ่งมีเพียงสองพารามิเตอร์) โดยเฉพาะอย่างยิ่งเนื่องจาก fprintf ตรงกันข้าม
user877329

คำตอบที่อร่อยที่สุด พูดได้ดีมาก
อันวาร์

31

ขอบคุณมากสำหรับคำตอบทั้งหมดของคุณ:

  • เป็นเรื่องที่น่าแปลกใจที่พบคนที่คิดว่า (เช่นฉัน) ว่าพารามิเตอร์ 5 ตัวนั้นเป็นขีด จำกัด ที่ดีสำหรับความมีเหตุผลของรหัส

  • โดยทั่วไปแล้วคนมักจะเห็นด้วยว่าข้อ จำกัด ระหว่าง 3 และ 4 เป็นกฎง่ายๆ นี่คือเหตุผลที่คนมักจะมีช่วงเวลาที่ไม่ดีนับมากกว่า 4 สิ่ง

  • ในฐานะที่เป็นคะแนนของมิลานคนทั่วไปสามารถรักษาสิ่งต่าง ๆ ไว้ในใจได้มากกว่า 7 รายการในแต่ละครั้ง แต่ฉันคิดว่าคุณไม่สามารถลืมได้ว่าเมื่อคุณออกแบบ / บำรุงรักษา / ศึกษากิจวัตรคุณต้องจำสิ่งต่าง ๆ มากกว่าพารามิเตอร์

  • บางคนพิจารณาว่ารูทีนควรมีอาร์กิวเมนต์มากเท่าที่ต้องการ ฉันเห็นด้วย แต่เฉพาะบางกรณีเท่านั้น (การเรียกไปยัง OS APIs, รูทีนที่การเพิ่มประสิทธิภาพมีความสำคัญ ฯลฯ ) ฉันขอแนะนำให้ซ่อนความซับซ้อนของรูทีนเหล่านี้โดยเพิ่มเลเยอร์ของ abstraction เหนือการเรียกเหล่านี้ทุกครั้งที่ทำได้

  • นิคมีความคิดที่น่าสนใจเกี่ยวกับเรื่องนี้ หากคุณไม่ต้องการอ่านความคิดเห็นของเขาฉันสรุปให้คุณ: สั้น ๆมันขึ้นอยู่กับ :

    ฉันเกลียดการสร้างกฎที่ยากและรวดเร็วเช่นนี้เพราะคำตอบไม่เพียง แต่เปลี่ยนไปขึ้นอยู่กับขนาดและขอบเขตของโครงการของคุณ แต่ฉันคิดว่ามันเปลี่ยนไปถึงระดับโมดูล ขึ้นอยู่กับว่าวิธีการของคุณกำลังทำอยู่หรือคลาสใดควรเป็นตัวแทนมันเป็นไปได้มากที่การโต้แย้ง 2 ข้อนั้นมากเกินไปและเป็นอาการของการมีเพศสัมพันธ์มากเกินไป

    คุณธรรมที่นี่คือไม่ต้องกลัวในการแสดงรหัสของคุณกับเพื่อนของคุณพูดคุยกับพวกเขาและพยายามที่จะ"ระบุพื้นที่ที่คุณมีการทำงานร่วมกันในระดับต่ำและมีเพศสัมพันธ์แน่น"

  • ในที่สุดฉันคิดว่าwnoiseเห็นด้วยกับ Nick และสรุปผลงานเหน็บแนมของเขาด้วยวิสัยทัศน์กวี (ดูความคิดเห็นด้านล่าง) ของศิลปะการเขียนโปรแกรม:

    การเขียนโปรแกรมไม่ใช่วิศวกรรม การจัดระเบียบของรหัสเป็นศิลปะเพราะขึ้นอยู่กับปัจจัยมนุษย์ซึ่งขึ้นอยู่กับบริบทมากเกินไปสำหรับกฎที่ยากใด ๆ


16

คำตอบนี้ถือว่าเป็นภาษา OO หากคุณไม่ได้ใช้งานให้ข้ามคำตอบนี้ (นี่ไม่ใช่คำตอบที่ไม่เชื่อเรื่องภาษาเลยในคำอื่น ๆ

หากคุณผ่านพารามิเตอร์มากกว่า 3 ตัวขึ้นไป (โดยเฉพาะอย่างยิ่งประเภท / วัตถุที่แท้จริง) ไม่ใช่ว่ามันเป็น "มากเกินไป" แต่คุณอาจพลาดโอกาสที่จะสร้างวัตถุใหม่

ค้นหากลุ่มของพารามิเตอร์ที่ผ่านเข้ามามากกว่าหนึ่งวิธี - แม้แต่กลุ่มที่ส่งผ่านไปยังสองวิธีเกือบจะรับประกันได้ว่าคุณควรมีวัตถุใหม่ที่นั่น

จากนั้นคุณปรับการทำงานให้เป็นวัตถุใหม่ของคุณและคุณจะไม่เชื่อเลยว่ามันจะช่วยได้มากแค่ไหนในโค้ดของคุณและความเข้าใจในการเขียนโปรแกรม OO


กรุณาตั้งชื่อภาษาที่ไม่ได้ใช้รูทีนและพารามิเตอร์ ฉันไม่สามารถนึกถึงสิ่งใดสิ่งหนึ่งได้แม้แต่การประกอบก็อาจถือว่าเป็นกิจวัตร (ป้ายกำกับ)
Auron

แอสเซมบลี x86 มีรูทีนแน่นอน (การโทร / ส่งคืน) อื่น ๆ อาจต้องใช้คอมโบ cmp / jmp
Brian Knoblauch

ขออภัย "ret" ไม่ใช่ "return" ถอนหายใจ มันเป็นวันที่ยาวนานมาแล้ว
Brian Knoblauch

ขออภัยเกี่ยวกับ Auron ถ้อยคำคลุมเครือฉันเชื่อว่าฉันแก้ไข มันเป็นคำตอบของฉันที่เฉพาะภาษาไม่ใช่คำถาม
Bill K

1
ไม่ใช่ทุกภาษาที่อนุญาตให้ผ่านโครงสร้าง นอกจากนี้การผ่านโครงสร้างหมายความว่าวิธีการรับจะต้องมีรหัสเพื่อจัดการโครงสร้างและดังนั้นจึงอาจต้องการพารามิเตอร์เพิ่มเติม นอกจากนี้ในภาษาที่ไม่ใช่ oo โดยทั่วไปคุณต้องมีพารามิเตอร์พิเศษ - ทุกภาษา OO มีพารามิเตอร์ "ซ่อน" ของ "นี้" ที่ควรจะผ่านเป็นอย่างอื่น (หรือในภาษา / การออกแบบที่น่ากลัวมากขึ้นอาจจะทั่วโลก เข้าถึงได้)
Bill K

13

ดูเหมือนว่ามีข้อควรพิจารณาอื่น ๆ นอกเหนือจากจำนวนเท่านั้นนี่คือสิ่งที่ควรคำนึงถึง:

  1. ความสัมพันธ์เชิงตรรกะกับวัตถุประสงค์หลักของฟังก์ชันเทียบกับการตั้งค่าแบบครั้งเดียว

  2. หากพวกเขาเป็นเพียงแค่ธงสภาพแวดล้อมการรวมกลุ่มอาจมีประโยชน์มาก


12

หนึ่งในรูปแบบการเขียนโปรแกรมที่รู้จักกันดีของ Alan Perlis (เล่าใน ACM SIGPLAN ประกาศ 17 (9), กันยายน, 1982) ระบุว่า "ถ้าคุณมีโพรซีเดอร์ที่มี 10 พารามิเตอร์คุณอาจพลาดบางส่วน"


11

ตาม Steve McConnell ในCode Completeคุณควร

จำกัด จำนวนพารามิเตอร์ของรูทีนเป็นประมาณเจ็ด


3
/: ตัวเลขแสดงว่า factoid ถูกสร้างขึ้น: xkcd.com/899
user877329

9

สำหรับฉันเมื่อรายการข้ามหนึ่งบรรทัดใน IDE ของฉันแล้วมันเป็นหนึ่งพารามิเตอร์มากเกินไป ฉันต้องการดูพารามิเตอร์ทั้งหมดในหนึ่งบรรทัดโดยไม่สบตา แต่นั่นเป็นเพียงความชอบส่วนตัวของฉัน


นี่เป็นสิ่งที่ดีจนกว่าคุณจะมีผู้พัฒนาบางคนจะลองใช้ foo (int a, float b, string c, double d) ดีที่สุดที่จะพยายามหลีกเลี่ยงการทำงานกับพวกเขาฉันเดา : D
Rontologist

4
หากมีคนอื่นให้ชื่อที่ยาวเหยียดในชั้นเรียนฉันจะไม่ปล่อยให้สิ่งนั้นมีอิทธิพลต่อวิธีที่ฉันกำหนดหรือเรียกกิจวัตรของฉัน
finnw

9
ฉันขอแนะนำคุณกับ "carriage return" ได้ไหม?

3
เมื่อรายการข้ามหนึ่งบรรทัดบน IDE ของคุณแล้วจอภาพของคุณเล็กเกินไปที่จะใช้กับโค้ดนั้นและคุณควรซื้อจอภาพที่มีความละเอียดแนวนอนสูงขึ้นอย่างชัดเจน การแบ่งบรรทัดหรือการลดจำนวนพารามิเตอร์เป็นเพียงวิธีการแก้ปัญหาที่ไม่สามารถแก้ไขปัญหารากซึ่งเป็นที่จอภาพของคุณมีขนาดเล็กเกินไปสำหรับ codebase นั้น!
Kaiserludi

9

โดยทั่วไปฉันเห็นด้วยกับ 5 อย่างไรก็ตามหากมีสถานการณ์ที่ฉันต้องการมากขึ้นและเป็นวิธีที่ชัดเจนที่สุดในการแก้ปัญหาฉันจะใช้มากกว่านี้


8

เจ็ดสิ่งในความทรงจำระยะสั้น?

  1. ชื่อของฟังก์ชั่น
  2. ส่งคืนค่าของฟังก์ชัน
  3. วัตถุประสงค์การใช้งาน
  4. พารามิเตอร์ 1
  5. พารามิเตอร์ 2
  6. พารามิเตอร์ 3
  7. พารามิเตอร์ 4

ดี. มันเป็นกฎง่ายๆ เมื่อคุณกำลังเขียนเนื้อความของฟังก์ชันคุณไม่สนใจชื่อของมันและค่าที่ส่งคืนและ purporse นั้นเกี่ยวข้องกันอย่างใกล้ชิด
Auron

7
8. ลำดับพารามิเตอร์
Eva

7

ในตัวอย่างโค้ดที่แย่ที่สุด 5ให้ตรวจสอบอันที่สอง "นี่คือตัวสร้าง" มันมีพารามิเตอร์มากกว่า 37 ⋅ 4 ≈ 150:

ที่นี่โปรแกรมเมอร์เขียนคอนสตรัคนี้ [... S] ome ของคุณอาจคิดว่าใช่มันเป็นคอนสตรัคเตอร์ขนาดใหญ่ แต่เขาใช้เครื่องมือสร้างโค้ดอัตโนมัติคราส [.] NOO ในคอนสตรัคเตอร์นี้มีข้อบกพร่องเล็ก ๆ ที่ฉันค้นพบซึ่งทำให้ฉัน สรุปว่าคอนสตรัคนี้เขียนด้วยมือ (โดยวิธีนี้เป็นเพียงส่วนบนของตัวสร้างมันไม่สมบูรณ์)

ตัวสร้างที่มีมากกว่า 150 พารามิเตอร์


มันช่างเศร้าเหลือเกิน ... ไม่รู้ว่า "records" หรือ "structs" หรือ "object value" ซึ่งรวมหลาย ๆ ค่าเข้าด้วยกันแล้วตั้งชื่อสามัญให้พวกมัน กับรองเท้า unlaced สำหรับปีเพราะไม่มีใครเคยบอกคุณแล้วคุณยังสามารถดำเนินการได้🙈
องค์รักษ์

6

เกินความจำเป็น ฉันไม่ได้ตั้งใจจะพูดจาโผงผาง แต่มีบางฟังก์ชั่นที่จำเป็นต้องมีตัวเลือกค่อนข้างน้อย ตัวอย่างเช่น:

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

มีข้อโต้แย้งทั้งหมด 6 ข้อและทุกข้อมีความสำคัญ นอกจากนี้ไม่มีการเชื่อมโยงทั่วไประหว่างพวกเขาเพื่อปรับการรวมกลุ่มพวกเขา บางทีคุณอาจนิยาม "struct mmapargs" แต่มันจะแย่กว่านั้น


ดีprotและflagsอาจถูกรีดเข้าด้วยกันถ้าผู้ออกแบบรู้สึกว่า 5 เป็นเลขอาถรรพ์ที่ดีกว่า 6 เล็กน้อยเหมือนกับวิธีที่openรวมโหมดการอ่าน / เขียนเข้ากับธงเบ็ดเตล็ดอื่น ๆ ทั้งหมด และบางทีคุณอาจจะได้รับการกำจัดโดยการระบุว่าแมปส่วนเริ่มต้นที่ปัจจุบันแสวงหาตำแหน่งของoffset filedesฉันไม่รู้ว่ามีสถานการณ์ใดบ้างที่คุณสามารถmmapภูมิภาคที่คุณไม่สามารถlseekเข้าร่วมได้ แต่ถ้าไม่เช่นนั้นมันก็ไม่จำเป็นอย่างเด็ดขาด
Steve Jessop

... ดังนั้นฉันคิดว่าmmapเป็นภาพประกอบที่ดีเกี่ยวกับความจริงที่ว่าผู้ออกแบบและผู้ใช้บางคนชอบรายการพารามิเตอร์ที่ยาวมากในขณะที่คนอื่นชอบทำตามขั้นตอนสองสามขั้นตอนเพื่อเตรียมพารามิเตอร์จำนวนน้อยลงก่อนที่จะโทรออก
Steve Jessop

1
@Steve: การตั้งค่าตำแหน่งค้นหาด้วยการโทรแยกต่างหากล่วงหน้าจะทำให้เกิดสภาพการแข่งขันที่ไม่ต้องเสียค่าใช้จ่าย สำหรับ API บางตัว (OpenGL) มีพารามิเตอร์มากมายที่ส่งผลต่อการโทรที่คุณต้องใช้สถานะ แต่จริงๆแล้วการโทรทุกครั้งควรอยู่คนเดียวให้มากที่สุด การกระทำที่ระยะทางคือเส้นทางสู่ด้านมืด
Ben Voigt

5

ตามPerl Best Practices 3 คือไม่เป็นไร 4 ก็มากเกินไป มันเป็นแค่แนวทาง แต่ในร้านของเรานั่นคือสิ่งที่เราพยายามทำ


5

ฉันจะวาดขีด จำกัด สำหรับฟังก์ชั่นสาธารณะที่ 5 พารามิเตอร์ด้วยตัวเอง

IMHO รายการพารามิเตอร์แบบยาวเป็นที่ยอมรับเฉพาะในฟังก์ชั่นตัวช่วยส่วนตัว / ท้องถิ่นที่มีความหมายเท่านั้นที่จะถูกเรียกจากสถานที่เฉพาะบางแห่งในรหัส ในกรณีดังกล่าวคุณอาจจำเป็นต้องส่งผ่านข้อมูลสถานะจำนวนมาก แต่การอ่านไม่ได้เป็นเรื่องใหญ่เพราะมีเพียงคุณเท่านั้น (หรือคนที่จะรักษารหัสของคุณและควรเข้าใจพื้นฐานของโมดูลของคุณ) ต้องใส่ใจ เรียกฟังก์ชั่นนั้น


ซึ่งทำไมผู้คนมากมายถึงจุดนี้จะทำให้ทุกอย่างที่ไม่ใช่ข้อโต้แย้งที่เกิดขึ้นจริง แต่รัฐดำเนินการเพียงรัฐของวัตถุในรูปแบบของเขตข้อมูล (ตัวแปรสมาชิก) วัตถุนั้นจะถูกแสดงเป็นคลาส มันจะถูกยกตัวอย่างเช่นครั้งเดียวหรือสำหรับการใช้งานทุกครั้ง บางครั้งวัตถุดังกล่าวจะมีวิธีการแพคเกจส่วนตัวหรือสาธารณะเพียงอย่างเดียวซึ่งผู้ได้รับมอบหมายทำงานกับวิธีการส่วนตัวที่มีข้อโต้แย้งเล็กน้อยในแต่ละ ข้อโต้แย้งไม่กี่ตอนนี้ไปได้เนื่องจากการตั้งค่าและรัฐตอนนี้มีสถานที่ที่เหมาะสม :)
องค์รักษ์

5

คำถามที่เกี่ยวข้องที่คุณควรพิจารณาคือการประสานงานประจำเป็นอย่างไร พารามิเตอร์จำนวนมากอาจเป็นกลิ่นที่บอกคุณว่ารูทีนเองกำลังพยายามทำมากเกินไปและด้วยเหตุนี้จึงสงสัยว่าการทำงานร่วมกัน ฉันยอมรับว่าพารามิเตอร์จำนวนมากและเร็วอาจเป็นไปไม่ได้ แต่ฉันเดาว่ารูทีนการทำงานร่วมกันที่สูงจะหมายถึงจำนวนพารามิเตอร์ต่ำ



4

ฉันหยุดที่สามพารามิเตอร์เป็นกฎทั่วไปของหัวแม่มือ อีกต่อไปและถึงเวลาส่งผ่านอาร์เรย์ของพารามิเตอร์หรือวัตถุการกำหนดค่าแทนซึ่งช่วยให้สามารถเพิ่มพารามิเตอร์ในอนาคตได้โดยไม่ต้องเปลี่ยน API


หาก API เปลี่ยนแปลงดังนั้น API ควรเปลี่ยนแปลงจริง ๆ ไม่ใช่เพียงแค่การเปลี่ยนแปลงอย่างซ่อนเร้นที่ซึ่งความเข้ากันไม่ได้อาจยังคงเกิดขึ้น แต่ชัดเจนน้อยกว่า
wnoise

อย่างไรก็ตามหากคุณต้องการพารามิเตอร์อีกหนึ่งพารามิเตอร์สำหรับการกำหนดค่าตัวพิมพ์ขอบมันไม่ควรเผยแพร่ไปยังส่วนประกอบที่ไม่เกี่ยวข้องโดยใช้ API
Eran Galperin

4

การจำกัดความยาวในรายการพารามิเตอร์เป็นข้อ จำกัด อีกหนึ่งข้อเท่านั้น และข้อ จำกัด หมายถึงการใช้ความรุนแรง ฟังดูตลก แต่คุณสามารถใช้ความรุนแรงได้แม้ในขณะที่เขียนโปรแกรม เพียงแค่ปล่อยให้รหัสกำหนดกฎ เห็นได้ชัดว่าถ้าคุณมีพารามิเตอร์หลายตัวเนื้อหาของฟังก์ชัน / คลาสจะมีขนาดใหญ่พอที่จะใช้ประโยชน์ได้ และโค้ดขนาดใหญ่มักจะสามารถ refactored และแยกออกเป็นชิ้นเล็ก ๆ ดังนั้นคุณจะได้รับการแก้ปัญหาเมื่อมีพารามิเตอร์จำนวนมากเป็นโบนัสฟรีเนื่องจากจะถูกแบ่งออกเป็นส่วนย่อย ๆ ของโค้ด


4

สิ่งหนึ่งที่ฉันจะชี้ให้เห็นจากมุมมองด้านประสิทธิภาพคือขึ้นอยู่กับว่าคุณส่งพารามิเตอร์ไปยังวิธีการอย่างไรการส่งผ่านพารามิเตอร์จำนวนมากตามค่าจะทำให้โปรแกรมช้าลงเนื่องจากแต่ละพารามิเตอร์ต้องคัดลอกแล้ววางลงบนสแต็ก

การใช้คลาสเดี่ยวเพื่อรวมพารามิเตอร์ทั้งหมดจะทำงานได้ดีขึ้นเพราะพารามิเตอร์เดียวที่ส่งผ่านโดยการอ้างอิงจะสวยงามและสะอาดตาและรวดเร็วยิ่งขึ้น!


ฉันจะให้คำตอบนี้ +1 เพราะมันเป็นเพียงคนเดียวที่พูดถึงอะไรนอกเหนือจากข้อ จำกัด ของรหัสความสะอาดหรือข้อ จำกัด โดยพลการซึ่งเป็นอัตนัย บางคนอาจไม่คิดเกี่ยวกับสิ่งที่คุณทำกับสแต็กเมื่อคุณอยู่ในลูปและกดอาร์กิวเมนต์หลายสิบครั้งเพื่อเปิดและปิดสแต็ก หากอยู่ในลูปคุณควรพิจารณาใช้จำนวนอาร์กิวเมนต์ที่ส่งผ่านโดย REGISTERS ใน ABI ที่คุณกำลังรวบรวม ตัวอย่างเช่นใน MS x64 ABI จำนวนสูงสุดของ args ที่ผ่านการลงทะเบียนคือ 4 "System V" ABI (ใช้โดยระบบปฏิบัติการที่ไม่ใช่ Windows) ใช้การลงทะเบียนมากขึ้นดังนั้นการใช้ 4 args พกพาได้สวย
Lakey

3

ตามที่ฉันอาจมีกรณีที่คุณจะเกิน 4 หรือจำนวนคงที่ สิ่งที่ควรระวังคือ

  1. วิธีการของคุณกำลังทำมากเกินไปและคุณจำเป็นต้องปรับโครงสร้าง
  2. คุณอาจต้องการพิจารณาใช้คอลเล็กชันหรือโครงสร้างข้อมูลบางอย่าง
  3. ทบทวนการออกแบบชั้นเรียนของคุณบางทีบางสิ่งไม่จำเป็นต้องผ่าน

จากมุมที่ใช้งานง่ายหรือง่ายต่อการอ่านรหัสฉันคิดว่าเมื่อคุณต้องการ "word wrap" ลายเซ็นวิธีการของคุณที่จะทำให้คุณหยุดและคิดว่าถ้าคุณรู้สึกหมดหนทางและความพยายามในการทำให้ลายเซ็นเล็กลง ไม่มีผลลัพธ์. ห้องสมุดที่ดีมาก ๆ ทั้งในอดีตและปัจจุบันใช้รถเข็นมากกว่า 4-5 คัน


3

กฎง่ายๆของฉันคือฉันต้องจำพารามิเตอร์ได้นานพอที่จะดูสายและบอกว่ามันทำอะไร ดังนั้นถ้าฉันไม่สามารถดูวิธีแล้วพลิกไปที่การเรียกเมธอดและจำพารามิเตอร์ที่ทำในสิ่งที่มีมากเกินไป

สำหรับฉันที่เท่ากับ 5 แต่ฉันไม่ได้สดใส ไมล์สะสมของคุณอาจแตกต่างกันไป

คุณสามารถสร้างวัตถุที่มีคุณสมบัติเพื่อเก็บพารามิเตอร์และส่งผ่านสิ่งนั้นหากคุณเกินขีด จำกัด ที่คุณตั้งไว้ ดูหนังสือRefactoringของ Martin Fowler และบทเกี่ยวกับการทำให้วิธีการเรียกใช้ง่ายขึ้น


1

มันขึ้นอยู่กับสภาพแวดล้อมที่คุณใช้งานเป็นอย่างมากยกตัวอย่างเช่นจาวาสคริปต์ ในจาวาสคริปต์วิธีที่ดีที่สุดในการส่งผ่านพารามิเตอร์คือการใช้วัตถุที่มีคู่คีย์ / ค่าซึ่งในทางปฏิบัติหมายความว่าคุณมีเพียงพารามิเตอร์เดียวเท่านั้น ในระบบอื่น ๆ จุดหวานจะอยู่ที่สามหรือสี่

ในท้ายที่สุดมันก็เดือดเพื่อความเป็นส่วนตัว


1

ฉันจะเห็นด้วยกับ 3 ก็โอเค 4 เป็นแนวทางมากเกินไป ด้วยพารามิเตอร์มากกว่า 3 ตัวคุณจะต้องทำมากกว่าหนึ่งภารกิจ ควรแยกงานมากกว่าหนึ่งอย่างออกเป็นวิธีแยกต่างหาก

อย่างไรก็ตามถ้าฉันดูโครงการล่าสุดที่ฉันทำไปข้อยกเว้นจะมีอยู่มากมายและส่วนใหญ่ก็ยากที่จะลดลงได้ถึง 3 พารามิเตอร์


1

ถ้าฉันมีพารามิเตอร์ 7-10 ตัวในหนึ่งรูทีนฉันดูที่การรวมมันเข้ากับคลาสใหม่แต่ไม่ใช่ถ้าคลาสนั้นจะไม่มีอะไรนอกจากกลุ่มของฟิลด์กับ getters และ setters - คลาสใหม่ต้องทำสิ่งอื่นนอกเหนือจากค่าสับเปลี่ยนในและ ออก. มิฉะนั้นฉันควรจะทนกับรายการพารามิเตอร์ยาว


1
ฉันจะรวมมันกับคลาส data-only ถ้ามันถูกใช้ในมากกว่าหนึ่งที่ แต่ถึงอย่างนั้นฉันก็มักจะสร้าง constructor ทั้งสอง
Leahn Novash

1

เป็นที่ทราบกันโดยทั่วไปแล้วว่าโดยทั่วไปผู้คนสามารถเก็บ 7 +/- 2 สิ่งไว้ในหัวได้ตลอดเวลา ฉันชอบที่จะใช้หลักการนั้นกับพารามิเตอร์ สมมติว่าโปรแกรมเมอร์ทุกคนฉลาดกว่าค่าเฉลี่ยฉันจะบอกว่าทุกอย่าง 10+ มากเกินไป

BTW ถ้าพารามิเตอร์คล้ายกัน แต่อย่างใดฉันจะใส่มันลงในเวกเตอร์หรือลิสต์แทนที่จะเป็นแบบโครงสร้างหรือคลาส


1

ฉันต้องการคำตอบของฉันว่าฟังก์ชั่นนี้ถูกเรียกบ่อยแค่ไหน

ถ้ามันเป็นฟังก์ชั่นเริ่มต้นที่เคยถูกเรียกเพียงครั้งเดียวแล้วให้ใช้เวลา 10 parms หรือมากกว่านั้นใครสนใจ

หากเรียกว่าหลายครั้งต่อเฟรมฉันก็มักจะสร้างโครงสร้างและเพียงส่งตัวชี้ไปที่มันเนื่องจากมันมีแนวโน้มที่จะเร็วขึ้น (สมมติว่าคุณไม่ได้สร้างโครงสร้างขึ้นใหม่ทุกครั้งเช่นกัน)


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.