การใช้งานสายอักขระ / หมายเลข [ปิด]


31

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

ในที่ทำงานของฉันเรามีแนวทางการเข้ารหัสที่เข้มงวด ส่วนหนึ่งของนั้นจะทุ่มเทให้กับสายอักขระ / หมายเลข มันระบุ (สำหรับ C #):

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

public class Whatever  
{  
   public static readonly Color PapayaWhip = new Color(0xFFEFD5);  
   public const int MaxNumberOfWheels = 18;  
}

มีข้อยกเว้นคือค่า 0, 1 และ null สามารถใช้ได้อย่างปลอดภัยเกือบตลอดเวลา บ่อยครั้งที่ค่า 2 และ -1 ก็โอเคเช่นกัน สตริงที่มีไว้สำหรับการบันทึกหรือการติดตามได้รับการยกเว้นจากกฎนี้ อนุญาตให้ใช้ตัวอักษรเมื่อความหมายชัดเจนจากบริบทและไม่ขึ้นอยู่กับการเปลี่ยนแปลงในอนาคต

mean = (a + b) / 2; // okay  
WaitMilliseconds(waitTimeInSeconds * 1000); // clear enough

สถานการณ์ในอุดมคติจะเป็นรายงานการวิจัยอย่างเป็นทางการที่แสดงผลกระทบต่อความสามารถในการอ่าน / การบำรุงรักษาโค้ดเมื่อ

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

ฉันอยากจะทำสิ่งนี้เพื่อให้มีข้อโต้แย้งเชิงวิทยาศาสตร์เมื่อโต้เถียงกับเพื่อนร่วมงานคนหนึ่งซึ่งกำลังจะประกาศค่าคงที่เช่น:

private const char SemiColon = ';';
private const char Space = ' ';
private const int NumberTen = 10;

อีกตัวอย่างหนึ่งคือ (และนี่คือ JavaScript):

var someNumericDisplay = new NumericDisplay("#Div_ID_Here");

คุณติด DOM ID ที่ด้านบนของไฟล์จาวาสคริปต์ของคุณหรือไม่หากใช้รหัสนั้นในที่เดียวเท่านั้น

ฉันได้อ่านหัวข้อต่อไปนี้:
StackExchange
StackOverflow
Bytes ชุมชน IT
มีบทความอีกมากมายและหลังจากอ่านรูปแบบบางอย่างเหล่านี้ก็โผล่ออกมา

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


2
ตัวแปรเวทมนต์เป็นตัวแปรที่เก็บความหมายที่ไม่สะท้อนโดยเนื้อหา ค่าจำนวนเต็ม '10' แสดงถึงความหมายของหมายเลข 10 ดังนั้นจึงไม่จำเป็นต้องทำให้มันคงที่ กันไปสำหรับพื้นที่และเครื่องหมายอัฒภาค ในทางกลับกันถ้าคุณมีค่า '%% ?? %%' และนี่คือตัวคั่นที่กำหนดเองดังนั้น HAS ที่จะถูกวางเป็นค่าคงที่เนื่องจากเนื้อหานั้นไม่ได้สะท้อนความจริงที่ว่ามันเป็นตัวคั่น
Jeroen Vannevel

23
NumberTen = 10นั่นไม่มีจุดหมายเพราะหมายเลข 10 จะไม่ถูกนิยามใหม่ MaxRetryCount = 10นั่นคือประเด็นที่เราอาจต้องการเปลี่ยนจำนวนการลองส่งใหม่สูงสุด private const char SemiColon = ';'; โง่. private const char LineTerminator = ';'; ฉลาด.
Mike

1
คำถามจริงไม่ชัดเจน
Tulains Córdova

คำตอบ:


89

... เมื่อโต้เถียงกับเพื่อนร่วมงานคนหนึ่งของฉันใครจะเป็นผู้ประกาศค่าคงที่เช่น:

private const char SemiColon = ';';
private const char Space = ' ';
private const int NumberTen = 10;

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

สมมติว่างานของรหัสของคุณคือการแยกวิเคราะห์กระแสข้อมูลที่มีเขตข้อมูลคั่นด้วยเครื่องหมายอัฒภาค ( a;b;c) และแยกด้วยช่องว่าง ( a;b;c d;e;f) หากใครก็ตามที่เขียนสเป็คของคุณโทรหาคุณในอีกหนึ่งเดือนข้างหน้าและพูดว่า "เราเข้าใจผิดฟิลด์ในบันทึกจะถูกคั่นด้วยสัญลักษณ์ไพพ์ ( a|b|c d|e|f)" คุณจะทำอย่างไร

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

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

private const char FieldSeparator = ';';    // Will become '|' a month from now
private const char RecordSeparator = ' ';
private const int MaxFieldsPerRecord = 10;

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


ฉันเห็นด้วยอย่างยิ่ง ไม่กี่ทศวรรษที่ผ่านมาฉันทำงานในโครงการที่มีการส่งข้อความเป็นกลุ่มแต่ละครั้งใช้รีจิสเตอร์ทั่วไป 8 ตัว ใครบางคนได้ประกาศ #define one 1 #define two 2 ฯลฯ (หรืออะไรก็ตามที่เทียบเท่าได้ใน Post Office Coral ของสหราชอาณาจักรภาษาที่เลือก) Word มาจากที่สูงว่าในอนาคตฟิลด์ความยาวจะเป็นจำนวนไบต์ไม่ใช่เซ็กเมนต์ดังนั้นจึงเห็นได้ชัดว่าโค้ดถูกเปลี่ยนเป็น #define one 8 #define two 16 ฯลฯ
Mawg

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

สิ่งที่เกี่ยวกับกรณีที่ตัวอักษรสตริงที่กำหนดจะใช้หลายครั้งในไฟล์ แต่มันไม่มีความหมายอื่นนอกเหนือจากค่าของมัน? ตัวอย่างเช่นหากคุณกำลังทดสอบว่าคุณสามารถรับคีย์บางอย่างในแผนที่ใน 20 สถานการณ์ที่แตกต่างกันฉันควรกำหนดค่าคงที่เช่นนี้หรือไม่: public static final String MY_KEY_NAME = "MyKeyName"
Jordan McQueen

1
@JordanMcQueen มีกรณีที่ต้องใช้ตัวอักษรเปลือยหาก (และเฉพาะในกรณี) แต่ละอันจะใช้เพียงครั้งเดียวและไม่จำเป็นต้องใช้ที่อื่น ถ้ามันเป็นสิ่งที่ต้องการเป็นรหัสแต่ละสถานการณ์ที่ประมวลผลรูปแบบไฟล์ที่แตกต่างกันในแต่ละรูปแบบควรกำหนดค่าคงที่ของตัวเอง (เช่นCSV_RECORD_SEPARATOR, TSV_RECORD_SEPARATORฯลฯ )
Blrfl

8

กำหนดอัฒภาคเป็นคงที่ซ้ำซ้อนเพราะอัฒภาคที่มีอยู่แล้วอย่างต่อเนื่องโดยตัวของมันเอง มันจะไม่เปลี่ยนไปเลย

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

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

การจัดเก็บการตั้งค่าทั้งหมดเป็น const เป็นสิ่งที่ฉันมีความคิดที่สองเกี่ยวกับเช่นกัน เราไม่ควรทำสิ่งนี้เบา ๆ

เราได้รวบรวมตัวอย่างการใช้งานประเภทใดบ้าง Line terminator ... จำนวนการลองซ้ำสูงสุด ... จำนวนล้อสูงสุด ... เราแน่ใจว่าสิ่งเหล่านี้จะไม่เปลี่ยนแปลงหรือไม่

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

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


4
"มันจะไม่เปลี่ยนแปลงตลอดไป" ฉันเคยคิดว่าเกี่ยวกับอะโพสโทรฟี (เชื่อมโยงกับค่า ASCII 39) แอปเก่า ๆ ที่ใช้ในการม้วนเครื่องหมายวรรคตอน แต่ตอนนี้แอปที่ทันสมัยถือว่าค่า ASCII เป็นเครื่องหมายวรรคตอนตรงเข้ากันได้กับแอปเก่าและคนมักจะใช้( Unicode 8217อ้างคำพูดเดียวซ้าย) สำหรับแอพที่เข้ากันได้กับการแสดงสัญลักษณ์ที่แตกต่างกันสำหรับเครื่องหมายโค้ง เนื่องจากว่ายุโรปใช้เครื่องหมายจุลภาคในลักษณะที่ชาวอเมริกันใช้จุดเป็นทศนิยมฉันจึงรู้สึกลังเลที่จะประกาศว่า "ไม่ ... เคย"
TOOGAM

@TOOGAM ดีตัวอย่างของคุณแสดงให้เห็นว่ามีDecimalPointค่าคงที่ - แต่ไม่ใช่CommaหรือPeriodค่าคงที่ มันค่อนข้างแตกต่าง: อดีตหมายถึงฟังก์ชั่นบทบาทหรือวัตถุประสงค์ของค่า "อัฒภาค" หรือ "เครื่องหมายจุลภาค" ไม่อยู่ในหมวดหมู่นั้น
Konrad Morawski

นั่นเป็นความจริงสำหรับตัวอย่างตำแหน่งทศนิยม อย่างไรก็ตามตัวอย่างอะพอสโทรฟีดูเหมือนจะเป็นหมวดหมู่ที่คล้ายกัน (หรือเหมือนกัน) เป็นเครื่องหมายจุลภาค (หรือเซมิโคลอน)
TOOGAM

@ KonradMorawski Semicolon สามารถใช้เพื่อวัตถุประสงค์หลายอย่างเช่นการแยกสตริงหรือสิ้นสุดบรรทัด มันเป็นความหมายของมัน (ไม่ใช่ค่า) ที่ควรใช้สำหรับการตั้งชื่อคอนสแตนซ์ พิจารณาการเปลี่ยนแปลงในอนาคตนั่นคือพรุ่งนี้เราอนุญาตให้ประมวลผล 20 รายการดังนั้นเนื้อหาที่มีชื่อเป็นNumberTenนั้นไม่อยู่ในบริบทขณะที่maxRecordก็ยังใช้ได้
MaxZoom

5
private const char SemiColon = ';';
private const char Space = ' ';
private const int NumberTen = 10;

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

private const char StatementTerminator = ';';
private const char Delimiter = ' ';
private const int  BalanceInquiryCode = 10;

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

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


3

ไม่ควรมีข้อโต้แย้งใด ๆ เกี่ยวกับเรื่องนี้ จุดไม่เกี่ยวกับการใช้ตัวเลขเวทย์มนตร์หรือไม่ประเด็นคือการมีรหัสที่สามารถอ่านได้
พิจารณาความแตกต่างระหว่าง: และif(request.StatusCode == 1) if(request.HasSucceeded)ในกรณีนี้ฉันจะเถียงว่าอันหลังนั้นอ่านง่ายกว่า แต่นั่นไม่ได้หมายความว่าคุณไม่สามารถมีรหัสint MaxNumberOfWheels = 18ได้

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


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

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

1
ฉันจะไม่ยืนยันว่าพวกเขาจะต้องเป็นทางการประทับ ฯลฯ พวกเขาสามารถเป็นทางการ แต่พวกเขาควรจะตกลงกันและสิ่งนี้ไปไกลกว่าเพียงแค่ใช้การตัดสินของแต่ละบุคคล แต่คุณลบความคิดเห็นของคุณตอนนี้สเตฟาน :)
Konrad Morawski

1
@StefanBilliet - ไม่เลย ประเด็นของฉันคือความสามารถในการอ่านได้รับการปรับปรุงผ่านความสอดคล้อง ปัญหาที่นี่ไม่ใช่แนวทางการเข้ารหัส แต่เป็นแนวทางที่นำไปสู่ความเข้าใจผิดอย่างสุดขั้ว
Mike Partridge

@ MikePartridge บางทีฉันควรจะทำอย่างละเอียด; แนวทางการเขียนโปรแกรมที่ผมเคยเห็นมีมากขึ้นในแนวโน้มของกฎหมายทั่วไปเกี่ยวกับวิธีการบางคนคิดว่าซอฟต์แวร์ที่ควรจะเขียนมากกว่าข้อตกลงเช่นคุณและคอนราดอาจจะเป็นความคิดของ :-)
สเตฟาน Billiet
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.