เป็นความคิดที่ดีหรือไม่ที่จะใส่รหัสลงในแอปพลิเคชันของเรา หรือเป็นสิ่งที่ถูกต้องเสมอที่จะเรียกค่าเหล่านี้แบบไดนามิกในกรณีที่จำเป็นต้องเปลี่ยนหรือไม่?
pi
การเปลี่ยนแปลงอาจจะ ...
เป็นความคิดที่ดีหรือไม่ที่จะใส่รหัสลงในแอปพลิเคชันของเรา หรือเป็นสิ่งที่ถูกต้องเสมอที่จะเรียกค่าเหล่านี้แบบไดนามิกในกรณีที่จำเป็นต้องเปลี่ยนหรือไม่?
pi
การเปลี่ยนแปลงอาจจะ ...
คำตอบ:
ใช่ แต่ไม่ทำให้มันเห็นได้ชัด
ทำ:
ไม่ได้:
diameter = 2 * radius
หรือdiameter = RADIUS_TO_DIAMETER_FACTOR * radius
? มีมุมกรณีที่จำนวนเวทมนตร์อาจเป็นทางออกที่ดีกว่า
diameter = radius << 1
อะไร ฉันคิดว่าอาจเป็นdiameter = radius << RADIUS_TO_DIAMETER_BITS_TO_SHIFT
เช่นนั้น
diameter = radius.toDiameter()
สิ่งที่ฉันพบแปลก ๆ เกี่ยวกับคำถามและคำตอบนี้คือไม่มีใครพยายามกำหนด "รหัสยาก" หรือทางเลือกอื่นที่สำคัญกว่าอย่างชัดเจน
TL; DR: ใช่มันเป็นบางครั้งก็เป็นความคิดที่ดีที่จะค่ายากรหัส แต่ไม่มีกฎง่ายๆเป็นไปได้เมื่อ ; มันขึ้นอยู่กับบริบทอย่างสมบูรณ์
คำถามที่ไม่แคบลงไปค่าซึ่งผมใช้เวลาในการหมายถึงหมายเลขมายากลแต่คำตอบหรือไม่ว่าพวกเขากำลังเป็นความคิดที่ดีคือเมื่อเทียบกับสิ่งที่พวกเขากำลังใช้จริง!
ตัวอย่างของค่า "ฮาร์ดโค้ด" คือ:
ค่าการกำหนดค่า
command.Timeout = 600
ฉันประจบประแจงเมื่อใดก็ตามที่ฉันเห็นชอบงบ ทำไมถึง 600 ใครเป็นคนตัดสินใจ มันเป็นช่วงเวลาก่อนหน้าหรือไม่และมีคนยกระดับการหมดเวลาเป็นแฮ็กแทนที่จะแก้ไขปัญหาประสิทธิภาพการทำงานพื้นฐานหรือไม่ หรือมันเป็นความคาดหวังบางอย่างที่ทราบและบันทึกไว้สำหรับการประมวลผลเวลา?
สิ่งเหล่านี้ไม่ควรเป็นเลขเวทย์มนตร์หรือค่าคงที่พวกเขาควรถูกทำให้เป็นภายนอกในไฟล์กำหนดค่าหรือฐานข้อมูลบางแห่งที่มีชื่อที่มีความหมายเพราะค่าที่ดีที่สุดของพวกเขาถูกกำหนดโดยส่วนใหญ่
สูตรทางคณิตศาสตร์
สูตรมักจะค่อนข้างคงที่เช่นลักษณะของค่าคงที่ภายในไม่สำคัญจริงๆ ปริมาตรของปิรามิดคือ (1/3) b * h เราสนใจที่ 1 หรือ 3 มาจากไหน? ไม่ได้จริงๆ ผู้วิจารณ์คนก่อนหน้าชี้ให้เห็นอย่างถูกต้องว่าdiameter = radius * 2
น่าจะดีกว่าdiameter = radius * RADIUS_TO_DIAMETER_CONVERSION_FACTOR
- แต่นั่นคือการแบ่งขั้วที่ผิด
สิ่งที่คุณควรจะทำสำหรับประเภทของสถานการณ์นี้คือการสร้างฟังก์ชั่น ฉันไม่จำเป็นต้องรู้ว่าคุณคิดสูตรอย่างไร แต่ก็ยังต้องรู้ว่ามันมีไว้เพื่ออะไร หากแทนที่จะเขียนเรื่องไร้สาระใด ๆ ข้างต้นฉันก็จะเขียนvolume = GetVolumeOfPyramid(base, height)
ทุกอย่างให้ชัดเจนขึ้นและมันก็โอเคที่จะมีหมายเลขเวทย์มนตร์ภายในฟังก์ชั่น ( return base * height / 3
) เพราะเห็นได้ชัดว่าพวกเขาเป็นเพียงส่วนหนึ่งของสูตร
กุญแจสำคัญที่นี่แน่นอนว่ามีฟังก์ชั่นสั้นและง่าย สิ่งนี้ใช้ไม่ได้กับฟังก์ชั่นที่มี 10 อาร์กิวเมนต์และ 30 บรรทัดการคำนวณ ใช้องค์ประกอบของฟังก์ชั่นหรือค่าคงที่ในกรณีนั้น
กฎโดเมน / ธุรกิจ
อันนี้เป็นพื้นที่สีเทาเสมอเพราะมันขึ้นอยู่กับว่าค่านั้นคืออะไร ส่วนใหญ่เป็นตัวเลขเวทย์มนตร์เฉพาะที่เป็นตัวเลือกในการเปลี่ยนเป็นค่าคงที่เนื่องจากทำให้โปรแกรมเข้าใจง่ายขึ้นโดยไม่ทำให้ตรรกะของโปรแกรมซับซ้อน พิจารณาการทดสอบif Age < 19
กับif Age < LegalDrinkingAge
; คุณอาจจะสามารถคิดได้ว่าเกิดอะไรขึ้นโดยไม่มีค่าคงที่ แต่มันง่ายขึ้นกับชื่อที่สื่อความหมาย
เหล่านี้อาจยังfunction isLegalDrinkingAge(age) { return age >= 19 }
กลายเป็นผู้สมัครที่เป็นนามธรรมฟังก์ชั่นเช่น สิ่งเดียวคือบ่อยครั้งที่ตรรกะทางธุรกิจของคุณมีความซับซ้อนมากกว่านั้นและอาจไม่เหมาะสมที่จะเริ่มเขียนฟังก์ชั่นมากมายด้วยพารามิเตอร์ 20-30 ตัว หากไม่มีสิ่งที่เป็นนามธรรมที่ชัดเจนตามวัตถุและ / หรือฟังก์ชั่นการใช้ค่าคงที่นั้นก็ถือว่าใช้ได้
ข้อแม้คือถ้าคุณกำลังทำงานสำหรับแผนกภาษีมันจะกลายเป็นจริงมันAttachForm(FORM_CODE_FOR_SINGLE_TAXPAYER_FILING_JOINTLY_FOR_DEPRECIATION_ON_ARMPIT_HAIR)
เป็นภาระหนักและตรงไปตรงมาไม่มีจุดหมายที่จะเขียน คุณจะไม่ทำอย่างนั้นคุณจะทำAttachForm("B-46")
เพราะนักพัฒนาทุกคนที่เคยทำงานหรือจะทำงานที่นั่นจะรู้ว่า "B-46" เป็นรหัสแบบฟอร์มสำหรับผู้เสียภาษีเพียงคนเดียวยื่น blah blah blah - รหัสแบบฟอร์มเป็นส่วนหนึ่งของโดเมนตัวเองพวกเขาไม่เคยเปลี่ยนดังนั้นพวกเขาไม่ได้เป็นตัวเลขมายากลจริงๆ
ดังนั้นคุณต้องใช้ค่าคงที่เท่าที่จำเป็นในตรรกะทางธุรกิจ โดยพื้นฐานแล้วคุณต้องเข้าใจว่า "หมายเลขเวทมนตร์" นั้นจริง ๆ แล้วเป็นหมายเลขเวทย์มนตร์หรือเป็นลักษณะที่รู้จักกันดีของโดเมน หากเป็นโดเมนคุณจะไม่ต้องพิมพ์รหัสให้เว้นเสียแต่ว่าจะมีโอกาสที่จะเปลี่ยนแปลงได้
รหัสข้อผิดพลาดและการตั้งค่าสถานะ
สิ่งเหล่านี้จะไม่โอเคสำหรับรหัสยากเนื่องจากไอ้เลวที่เคยถูกตีด้วยPrevious action failed due to error code 46
สามารถบอกคุณได้ หากภาษาของคุณรองรับคุณควรใช้ประเภทการแจงนับ มิฉะนั้นคุณมักจะมีทั้งไฟล์ / โมดูลที่เต็มไปด้วยค่าคงที่ที่ระบุค่าที่ถูกต้องสำหรับประเภทข้อผิดพลาดเฉพาะ
ไม่เคยให้ฉันเห็นreturn 42
ในตัวจัดการข้อผิดพลาด capiche? ไม่มีข้อแก้ตัว.
ฉันอาจจะทิ้งหลายสถานการณ์ แต่ฉันคิดว่ามันครอบคลุมมากที่สุด
ดังนั้นใช่บางครั้งมันก็เป็นวิธีปฏิบัติที่ยอมรับได้สำหรับสิ่งที่เป็นโค้ด อย่าเพิ่งขี้เกียจกับมัน มันควรจะเป็นการตัดสินใจที่มีสติมากกว่ารหัสเลอะเทอะเก่า ๆ
มีสาเหตุหลายประการในการกำหนดตัวระบุให้กับตัวเลข
สิ่งนี้ทำให้เรามีเกณฑ์สำหรับตัวอักษรที่เข้ารหัสยาก พวกเขาควรจะไม่เปลี่ยนรูปไม่ยากที่จะพิมพ์เกิดขึ้นในที่เดียวหรือบริบทเท่านั้นและมีความหมายที่รู้จัก ไม่มีจุดใดในการกำหนด 0 เป็น ARRAY_BEGINNING ตัวอย่างเช่นหรือ 1 เป็น ARRAY_INCREMENT
เป็นการเพิ่มเติมนอกเหนือจากคำตอบอื่น ๆ ใช้ค่าคงที่สำหรับสตริงเมื่อเป็นไปได้ แน่นอนคุณไม่ต้องการที่จะมี
const string server_var="server_var";
แต่คุณควรจะมี
const string MySelectQuery="select * from mytable;";
(สมมติว่าคุณมีแบบสอบถามที่คุณต้องการรับผลลัพธ์ทั้งหมดจากตารางที่ระบุเสมอ)
นอกเหนือจากนั้นให้ใช้ค่าคงที่สำหรับหมายเลขใด ๆ ที่ไม่ใช่ 0 (ปกติ) หากคุณต้องการสิทธิ์ bitmask 255 อย่าใช้
const int 8th_bit=255; //or some other obscure naming scheme that equates to 255.
ใช้แทน
const int AllowGlobalRead=255;
แน่นอนพร้อมกับค่าคงที่รู้ว่าเมื่อใดควรใช้ตัวแจงนับ กรณีข้างต้นอาจจะพอดีในหนึ่ง
typedef enum {init_state=0, parse_state=1, evaluation_state=2, ... }
มันขึ้นอยู่กับสิ่งที่คุณพิจารณาการเข้ารหัส หากคุณพยายามหลีกเลี่ยงสิ่งใด ๆ และฮาร์ดโค้ดทั้งหมดคุณก็จะสิ้นสุดลงในการทำซอฟต์โค้ดอาณาเขตของและสร้างระบบที่มีเพียงผู้สร้างเท่านั้นที่สามารถจัดการได้ (และเป็นฮาร์ดโค้ดที่ดีที่สุด)
สิ่งต่าง ๆ มากมายถูก hardcoded ในกรอบที่สมเหตุสมผลใด ๆ และพวกเขาทำงาน เช่นไม่มีเหตุผลทางเทคนิคว่าทำไมฉันไม่ควรเปลี่ยนจุดเริ่มต้นของแอปพลิเคชัน C # (หลักโมฆะคงที่) แต่การเข้ารหัสที่ไม่สร้างปัญหาให้กับผู้ใช้ (ยกเว้นคำถาม SOเป็นครั้งคราว)
กฎของหัวแม่มือที่ฉันใช้คือทุกสิ่งที่สามารถและจะเปลี่ยนแปลงได้โดยไม่กระทบต่อสถานะของระบบทั้งหมดควรจะสับสนได้
ดังนั้น IMHO มันเป็นเรื่องโง่ที่จะไม่ทำโค้ดสิ่งที่ไม่เคยเปลี่ยน (pi, ค่าคงตัวโน้มถ่วง, ค่าคงที่ในสูตรคณิตศาสตร์ - คิดปริมาตรของทรงกลม)
นอกจากนี้ยังเป็นเรื่องโง่ที่จะไม่เข้ารหัสสิ่งหรือกระบวนการที่จะมีผลกระทบต่อระบบของคุณที่จะต้องมีการเขียนโปรแกรมในกรณีใด ๆ เช่นมันเป็นการสูญเปล่าที่จะอนุญาตให้ผู้ใช้เพิ่มเขตข้อมูลแบบไดนามิกลงในแบบฟอร์ม เข้าไปข้างในและเขียนสคริปต์ที่จะทำให้สิ่งนั้นใช้ได้ผล นอกจากนี้มันโง่ (และฉันเห็นสองสามครั้งในสภาพแวดล้อมขององค์กร) เพื่อสร้างเครื่องมือกำหนดค่าบางอย่างดังนั้นจึงไม่มีฮาร์ดโค้ดใด ๆ เพียงนักพัฒนาในแผนกไอทีเท่านั้นที่สามารถใช้งานได้และมันใช้ง่ายกว่าเล็กน้อย ทำใน Visual Studio
ดังนั้นสิ่งที่ควรทำคือ hardcoded เป็นฟังก์ชั่นของตัวแปรสองตัว:
เป็นความคิดที่ดีหรือไม่ที่จะใส่รหัสลงในแอปพลิเคชันของเรา
ฉัน hardcode ค่าเฉพาะถ้าค่าที่ระบุไว้ในสเปค (ในรุ่นล่าสุดของสเปค) เช่นการตอบสนอง HTTP OK จะเป็น200
(เว้นแต่จะมีการเปลี่ยนแปลงใน RFC) ดังนั้นคุณจะเห็น (ในบางรหัสของฉัน ) ค่าคงที่เช่น:
public static final int HTTP_OK = 200;
มิฉะนั้นฉันจะเก็บค่าคงที่ในไฟล์คุณสมบัติ
เหตุผลที่ฉันระบุข้อกำหนดคือการเปลี่ยนค่าคงที่ในข้อกำหนดต้องใช้การจัดการการเปลี่ยนแปลงซึ่งผู้มีส่วนได้เสียจะตรวจสอบการเปลี่ยนแปลงและอนุมัติ / ไม่อนุมัติ มันไม่เคยเกิดขึ้นข้ามคืนและใช้เวลาเดือน / ปีสำหรับการอนุมัติ อย่าลืมว่านักพัฒนาซอฟต์แวร์จำนวนมากใช้ข้อกำหนด (เช่น HTTP) ดังนั้นการเปลี่ยนหมายถึงการทำลายระบบหลายล้านระบบ
ฉันสังเกตเห็นว่าเมื่อใดก็ตามที่คุณสามารถดึงข้อมูลจากรหัสของคุณมันจะปรับปรุงสิ่งที่เหลืออยู่ คุณเริ่มสังเกตเห็นการปรับโครงสร้างใหม่และปรับปรุงส่วนทั้งหมดของรหัสของคุณ
เป็นความคิดที่ดีที่จะทำงานเพื่อดึงค่าคงที่ออกมาอย่าคิดว่าเป็นกฎโง่ ๆ คิดว่ามันเป็นโอกาสที่จะเขียนโค้ดได้ดีขึ้น
ข้อได้เปรียบที่ใหญ่ที่สุดคือวิธีที่คุณอาจพบว่าค่าคงที่ที่คล้ายกันเป็นความแตกต่างเพียงอย่างเดียวในกลุ่มของรหัส - การทำให้พวกเขาเป็นอาร์เรย์ได้ช่วยให้ฉันลดไฟล์ลง 90% ของขนาดและแก้ไขข้อผิดพลาดในการคัดลอกและวาง .
ฉันยังไม่เห็นข้อได้เปรียบเดียวที่จะไม่แยกข้อมูล
ฉันเพิ่งเขียนฟังก์ชัน MySQL เพื่อคำนวณระยะทางระหว่างคู่ lat / long อย่างถูกต้อง คุณทำพีทาโกรัสไม่ได้ เส้นลองจิจูดเข้าใกล้กันมากขึ้นเมื่อละติจูดเพิ่มขึ้นไปทางขั้วดังนั้นจึงมีบางส่วนที่เกี่ยวข้อง ประเด็นก็คือฉันถูกดึงออกมาว่าจะเขียนโค้ดที่มีค่ารัศมีของโลกเป็นไมล์หรือไม่
ฉันลงเอยด้วยการทำแม้ว่าความจริงแล้วเส้นละติจูด / ลองจิจูดจะใกล้กันมากขึ้นกล่าวคือดวงจันทร์ และฟังก์ชั่นของฉันจะแสดงระยะทางระหว่างจุดบนดาวพฤหัสอย่างมาก ฉันคิดว่าอัตราต่อรองของเว็บไซต์ที่ฉันกำลังสร้างมีสถานที่ต่างดาวเข้ามาค่อนข้างผอมเพรียว
ขึ้นอยู่กับว่าภาษาของคุณถูกคอมไพล์แล้ว หากยังไม่ได้รวบรวมมันไม่ใช่เรื่องใหญ่คุณเพียงแค่แก้ไขซอร์สโค้ดแม้ว่ามันจะมีความละเอียดอ่อนเล็กน้อยสำหรับโปรแกรมเมอร์ที่ไม่ใช่
หากคุณกำลังเขียนโปรแกรมด้วยภาษาที่คอมไพล์นี่ไม่ใช่ความคิดที่ดีเพราะถ้าตัวแปรเปลี่ยนแปลงคุณต้องคอมไพล์ใหม่ซึ่งเป็นการเสียเวลามากหากคุณต้องการปรับตัวแปรนี้
คุณไม่จำเป็นต้องทำแถบเลื่อนหรืออินเทอร์เฟซเพื่อเปลี่ยนตัวแปรของเขาแบบไดนามิก แต่อย่างน้อยคุณก็สามารถทำได้คือไฟล์ข้อความ
เช่นกับโครงการผีปอบของฉันฉันมักจะใช้คลาส ConfigFile เพื่อโหลดตัวแปรที่ฉันเขียนไปยังไฟล์ปรับแต่ง
สองครั้งที่ค่าคงที่อยู่ (ในความคิดของฉันอย่างน้อย) ตกลง:
ค่าคงที่ที่เกี่ยวข้องกับอะไรอย่างอื่น; คุณสามารถเปลี่ยนค่าคงที่เหล่านั้นได้ทุกเมื่อที่คุณต้องการโดยไม่ต้องเปลี่ยนอะไรเลย ตัวอย่าง: ความกว้างเริ่มต้นของคอลัมน์กริด
ค่าคงที่ที่แน่นอนและชัดเจนไม่เปลี่ยนแปลงอย่างแน่นอนเช่น "จำนวนวันต่อสัปดาห์" days = weeks * 7
แทนที่7
ด้วยค่าคงที่DAYS_PER_WEEK
แทบจะไม่ให้ค่าใด ๆ
ฉันเห็นด้วยอย่างสมบูรณ์กับ Jonathan แต่เนื่องจากกฎทั้งหมดมีข้อยกเว้น ...
"หมายเลข Magic ในข้อมูลจำเพาะ: หมายเลข Magic ในรหัส"
โดยทั่วไประบุว่าหมายเลขอาถรรพ์ใด ๆ ที่ยังคงอยู่ในข้อมูลจำเพาะหลังจากความพยายามตามสมควรในการรับบริบทเชิงอธิบายสำหรับพวกเขาควรจะสะท้อนให้เห็นเช่นนี้ในรหัส หากตัวเลขเวทมนต์ยังคงอยู่ในรหัสความพยายามทุกอย่างควรทำเพื่อแยกพวกเขาและทำให้พวกเขาเชื่อมโยงอย่างชัดเจนกับจุดกำเนิดของพวกเขา
ฉันได้ทำสัญญาการเชื่อมต่อสองสามครั้งซึ่งจำเป็นต้องเติมข้อความด้วยค่าที่แมปจากฐานข้อมูล ในกรณีส่วนใหญ่การทำแผนที่ค่อนข้างตรงไปตรงมาและจะพอดีกับเส้นบอกแนวทั่วไปของโจนาธาน แต่ฉันได้พบกับกรณีที่โครงสร้างข้อความเป้าหมายนั้นแย่มาก มากกว่า 80% ของค่าที่ต้องส่งผ่านลงไปในโครงสร้างเป็นค่าคงที่ที่บังคับใช้โดยข้อกำหนดของระบบระยะไกล ประกอบกับความจริงที่ว่าโครงสร้างข้อความนั้นใหญ่โตทำให้ค่าคงที่จำนวนมากต้องถูกเติม ในกรณีส่วนใหญ่พวกเขาไม่ได้ให้ความหมายหรือเหตุผลเพียงแค่พูดว่า "ใส่ M ที่นี่" หรือ "ใส่ 4.10.53.10100.889450.4452 ที่นี่" ฉันไม่ได้พยายามที่จะใส่ความคิดเห็นถัดจากพวกเขาทั้งหมดมันจะแสดงผลรหัสที่อ่านไม่ได้
ที่กล่าวว่าเมื่อคุณคิดเกี่ยวกับมัน ... มันเกี่ยวกับการทำให้ชัดเจน ...
หากคุณกำลังเข้ารหัสคุณค่าของค่าความโน้มถ่วงคงที่ของโลกจะไม่มีใครสนใจ หากคุณเข้ารหัสที่อยู่ IP ของพร็อกซีเซิร์ฟเวอร์ของคุณคุณกำลังประสบปัญหา
ส่วนใหญ่ไม่ แต่ฉันคิดว่ามันคุ้มค่าที่จะสังเกตว่าคุณจะมีปัญหามากที่สุดเมื่อคุณเริ่มทำซ้ำค่าฮาร์ดโค้ด หากคุณไม่ทำซ้ำ (เช่นใช้เพียงครั้งเดียวในการใช้คลาส) ดังนั้นการไม่ใช้ค่าคงที่อาจไม่เป็นไร